remove libdss from Makefile
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / media / platform / exynos / fimc-is2 / sensor / module_framework / eeprom / fimc-is-sensor-eeprom-5e9.c
CommitLineData
f3af0f51
WK
1/*
2 * Samsung Exynos5 SoC series Sensor driver
3 *
4 *
5 * Copyright (c) 2018 Samsung Electronics Co., Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/i2c.h>
13#include <linux/time.h>
14#include <linux/slab.h>
15#include <linux/module.h>
16#include <linux/videodev2.h>
17#include <linux/videodev2_exynos_camera.h>
18#include <media/v4l2-ctrls.h>
19#include <media/v4l2-device.h>
20#include <media/v4l2-subdev.h>
21
22#include <exynos-fimc-is-sensor.h>
23#include "fimc-is-sensor-eeprom-5e9.h"
24#include "fimc-is-sensor-eeprom.h"
25#include "fimc-is-device-sensor.h"
26#include "fimc-is-device-sensor-peri.h"
27#include "fimc-is-core.h"
28
29#define SENSOR_EEPROM_NAME "5E9"
30
31int fimc_is_eeprom_5e9_check_all_crc(struct v4l2_subdev *subdev)
32{
33 int ret = 0;
34 struct fimc_is_module_enum *module;
35 struct fimc_is_eeprom *eeprom = NULL;
36 struct fimc_is_device_sensor *sensor = NULL;
37
38 FIMC_BUG(!subdev);
39
40 module = (struct fimc_is_module_enum *)v4l2_get_subdev_hostdata(subdev);
41
42 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
43
44 FIMC_BUG(!eeprom);
45 FIMC_BUG(!module);
46
47 sensor = (struct fimc_is_device_sensor *)v4l2_get_subdev_hostdata(module->subdev);
48 if (!sensor) {
49 err("device sensor is NULL");
50 ret = -ENODEV;
51 return ret;
52 }
53
54 /* Check CRC to Address cal data */
55 ret = CALL_EEPROMOPS(eeprom, eeprom_check_address, subdev);
56 if (ret) {
57 err("%s(): 5E9 EEPROM Address section CRC check fail(%d)", __func__, ret);
58
59 /* All calibration data is zero set only Address section is invalid CRC */
60 fimc_is_eeprom_cal_data_set(eeprom->data, "all",
0581d52f 61 EEPROM_ADD_CRC_FST, EEPROM_DATA_SIZE, 0xff);
f3af0f51
WK
62
63 /*Set all cal_status to ERROR if Address cal data invalid*/
64 for (int i = 0; i < CAMERA_CRC_INDEX_MAX; i++)
65 sensor->cal_status[i] = CRC_ERROR;
66
67 return ret;
68 } else
69 info("5E9 EEPROM Address section CRC check success\n");
70
71 /* Check CRC to Information cal data */
72 ret = CALL_EEPROMOPS(eeprom, eeprom_check_info, subdev);
73 if (ret) {
74 err("%s(): 5E9 EEPROM Information CRC section check fail(%d)", __func__, ret);
75
76 /* All calibration data is 0xff set but exception Address section */
77 fimc_is_eeprom_cal_data_set(eeprom->data, "Information - End",
0581d52f 78 EEPROM_INFO_CRC_FST, EEPROM_ADD_CAL_SIZE, 0xff);
f3af0f51
WK
79
80 sensor->cal_status[CAMERA_CRC_INDEX_MNF] = CRC_ERROR;
81
82 } else {
83 info("5E9 EEPROM Informaion section CRC check success\n");
84
85 sensor->cal_status[CAMERA_CRC_INDEX_MNF] = CRC_NO_ERROR;
86 }
87
88 /* Check CRC to AWB cal data */
89 ret = CALL_EEPROMOPS(eeprom, eeprom_check_awb, subdev);
90 if (ret) {
91 err("%s(): 5E9 EEPROM AWB section CRC check fail(%d)", __func__, ret);
92
93 fimc_is_eeprom_cal_data_set(eeprom->data, "AWB",
0581d52f 94 EEPROM_AWB_CRC_FST, EEPROM_AWB_CAL_SIZE, 0xff);
f3af0f51
WK
95
96 sensor->cal_status[CAMERA_CRC_INDEX_AWB] = CRC_ERROR;
97
98 } else {
99 info("5E9 EEPROM AWB section CRC check success\n");
100
101 sensor->cal_status[CAMERA_CRC_INDEX_AWB] = CRC_NO_ERROR;
102
103 ret = fimc_is_sensor_eeprom_check_awb_ratio(&eeprom->data[EEPROM_AWB_UNIT_OFFSET],
104 &eeprom->data[EEPROM_AWB_GOLDEN_OFFSET],&eeprom->data[EEPROM_AWB_LIMIT_OFFSET]);
105 if (ret) {
106 err("%s(): 5E9 EEPROM AWB ratio out of limit(%d)", __func__, ret);
107
108 sensor->cal_status[CAMERA_CRC_INDEX_AWB] = LIMIT_FAILURE;
109 }
110 }
111
112 /* Check CRC to LSC cal data */
113 ret = CALL_EEPROMOPS(eeprom, eeprom_check_lsc, subdev);
114 if (ret) {
115 err("%s(): 5E9 EEPROM LSC section CRC check fail(%d)", __func__, ret);
116
117 fimc_is_eeprom_cal_data_set(eeprom->data, "LSC",
0581d52f 118 EEPROM_LSC_CRC_FST, EEPROM_LSC_CAL_SIZE, 0xff);
f3af0f51
WK
119
120 } else
121 info("5E9 EEPROM LSC section CRC check success\n");
122
123 /* Check CRC to AE Sync cal data */
124 ret = CALL_EEPROMOPS(eeprom, eeprom_check_ae, subdev);
125 if (ret) {
126 err("%s(): 5E9 EEPROM AE section CRC check fail(%d)", __func__, ret);
127
128 fimc_is_eeprom_cal_data_set(eeprom->data, "AE",
0581d52f 129 EEPROM_AE_CRC_FST, EEPROM_AE_CAL_SIZE, 0xff);
f3af0f51
WK
130
131 } else
132 info("5E9 EEPROM AE section CRC check success\n");
133
134 /* Check CRC to SFR cal data */
135 ret = CALL_EEPROMOPS(eeprom, eeprom_check_sfr, subdev);
136 if (ret) {
137 err("%s(): EEPROM SFR section CRC check fail(%d)", __func__, ret);
138
139 fimc_is_eeprom_cal_data_set(eeprom->data, "SFR",
0581d52f 140 EEPROM_SFR_CRC_FST, EEPROM_SFR_CAL_SIZE, 0xff);
f3af0f51
WK
141
142 } else
143 info("5E9 EEPROM SFR section CRC check success\n");
144
f3af0f51
WK
145 return ret;
146}
147
148static int fimc_is_eeprom_5e9_check_address(struct v4l2_subdev *subdev)
149{
150 int ret = 0;
151 u16 crc_value = 0;
152 u16 crc16 = 0;
153 struct fimc_is_eeprom *eeprom = NULL;
154
155 FIMC_BUG(!subdev);
156
157 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
158
159 FIMC_BUG(!eeprom);
160
161 crc_value = ((eeprom->data[EEPROM_ADD_CRC_FST] << 8) | (eeprom->data[EEPROM_ADD_CRC_SEC]));
162
163 crc16 = fimc_is_sensor_eeprom_check_crc(&eeprom->data[EEPROM_ADD_CRC_CHK_START], EEPROM_ADD_CRC_CHK_SIZE);
164 if (crc_value != crc16) {
165 err("Error to ADD CRC16: 0x%x, cal_buffer CRC: 0x%x", crc16, crc_value);
166
167 ret = -EINVAL;
168 } else
169 info("ADD CRC16: 0x%x, cal_buffer CRC: 0x%x\n", crc16, crc_value);
170
171 return ret;
172}
173
174static int fimc_is_eeprom_5e9_check_info(struct v4l2_subdev *subdev)
175{
176 int ret = 0;
177 u16 crc_value = 0;
178 u16 crc16 = 0;
179 struct fimc_is_eeprom *eeprom = NULL;
180
181 FIMC_BUG(!subdev);
182
183 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
184
185 FIMC_BUG(!eeprom);
186
187 crc_value = ((eeprom->data[EEPROM_INFO_CRC_FST] << 8) | (eeprom->data[EEPROM_INFO_CRC_SEC]));
188
189 crc16 = fimc_is_sensor_eeprom_check_crc(&eeprom->data[EEPROM_INFO_CRC_CHK_START], EEPROM_INFO_CRC_CHK_SIZE);
0581d52f 190 if (crc_value != crc16) {
f3af0f51 191 err("Error to INFO CRC16: 0x%x, cal_buffer CRC: 0x%x", crc16, crc_value);
0581d52f 192
193 ret = -EINVAL;
194 } else
f3af0f51
WK
195 info("INFO CRC16: 0x%x, cal_buffer CRC: 0x%x\n", crc16, crc_value);
196
197 return ret;
198}
199
200static int fimc_is_eeprom_5e9_check_awb(struct v4l2_subdev *subdev)
201{
202 int ret = 0;
203 u16 crc_value = 0;
204 u16 crc16 = 0;
205 struct fimc_is_eeprom *eeprom = NULL;
206
207 FIMC_BUG(!subdev);
208
209 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
210
211 FIMC_BUG(!eeprom);
212
213 crc_value = ((eeprom->data[EEPROM_AWB_CRC_FST] << 8) | (eeprom->data[EEPROM_AWB_CRC_SEC]));
214
215 crc16 = fimc_is_sensor_eeprom_check_crc(&eeprom->data[EEPROM_AWB_CRC_CHK_START], EEPROM_AWB_CRC_CHK_SIZE);
0581d52f 216 if (crc_value != crc16) {
f3af0f51 217 err("Error to AWB CRC16: 0x%x, cal_buffer CRC: 0x%x", crc16, crc_value);
0581d52f 218
219 ret = -EINVAL;
220 } else
f3af0f51
WK
221 info("AWB CRC16: 0x%x, cal_buffer CRC: 0x%x\n", crc16, crc_value);
222
223 return ret;
224}
225
226static int fimc_is_eeprom_5e9_check_ae(struct v4l2_subdev *subdev)
227{
228 int ret = 0;
229 u16 crc_value = 0;
230 u16 crc16 = 0;
231 struct fimc_is_eeprom *eeprom = NULL;
232
233 FIMC_BUG(!subdev);
234
235 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
236
237 FIMC_BUG(!eeprom);
238
239 crc_value = ((eeprom->data[EEPROM_AE_CRC_FST] << 8) | (eeprom->data[EEPROM_AE_CRC_SEC]));
240
241 crc16 = fimc_is_sensor_eeprom_check_crc(&eeprom->data[EEPROM_AE_CRC_CHK_START], EEPROM_AE_CRC_CHK_SIZE);
0581d52f 242 if (crc_value != crc16) {
f3af0f51 243 err("Error to AE CRC16: 0x%x, cal_buffer CRC: 0x%x", crc16, crc_value);
0581d52f 244
245 ret = -EINVAL;
246 } else
f3af0f51
WK
247 info("AE CRC16: %x, cal_buffer CRC: %x\n", crc16, crc_value);
248
249 return ret;
250}
251
252static int fimc_is_eeprom_5e9_check_lsc(struct v4l2_subdev *subdev)
253{
254 int ret = 0;
255 u16 crc_value = 0;
256 u16 crc16 = 0;
257 struct fimc_is_eeprom *eeprom = NULL;
258
259 FIMC_BUG(!subdev);
260
261 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
262
263 FIMC_BUG(!eeprom);
264
265 crc_value = ((eeprom->data[EEPROM_LSC_CRC_FST] << 8) | (eeprom->data[EEPROM_LSC_CRC_SEC]));
266
267 crc16 = fimc_is_sensor_eeprom_check_crc(&eeprom->data[EEPROM_LSC_CRC_CHK_START], EEPROM_LSC_CRC_CHK_SIZE);
0581d52f 268 if (crc_value != crc16) {
f3af0f51 269 err("Error to LSC CRC16: 0x%x, cal_buffer CRC: 0x%x", crc16, crc_value);
0581d52f 270
271 ret = -EINVAL;
272 } else
f3af0f51
WK
273 info("LSC CRC16: 0x%x, cal_buffer CRC: 0x%x\n", crc16, crc_value);
274
275 return ret;
276}
277
278static int fimc_is_eeprom_5e9_check_sfr(struct v4l2_subdev *subdev)
279{
280 int ret = 0;
281 u16 crc_value = 0;
282 u16 crc16 = 0;
283 struct fimc_is_eeprom *eeprom = NULL;
284
285 FIMC_BUG(!subdev);
286
287 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
288
289 FIMC_BUG(!eeprom);
290
291 crc_value = ((eeprom->data[EEPROM_SFR_CRC_FST] << 8) | (eeprom->data[EEPROM_SFR_CRC_SEC]));
292
293 crc16 = fimc_is_sensor_eeprom_check_crc(&eeprom->data[EEPROM_SFR_CRC_CHK_START], EEPROM_SFR_CRC_CHK_SIZE);
0581d52f 294 if (crc_value != crc16) {
f3af0f51 295 err("Error to SFR CRC16: 0x%x, cal_buffer CRC: 0x%x", crc16, crc_value);
0581d52f 296
297 ret = -EINVAL;
298 } else
f3af0f51
WK
299 info("SFR CRC16: 0x%x, cal_buffer CRC: 0x%x\n", crc16, crc_value);
300
301 return ret;
302}
303
304int fimc_is_eeprom_5e9_get_cal_data(struct v4l2_subdev *subdev)
305{
306 int ret = 0;
307 struct fimc_is_eeprom *eeprom;
308 struct i2c_client *client;
309
310 FIMC_BUG(!subdev);
311
312 eeprom = (struct fimc_is_eeprom *)v4l2_get_subdevdata(subdev);
313
314 FIMC_BUG(!eeprom);
315
316 client = eeprom->client;
317 if (unlikely(!client)) {
318 err("client is NULL");
319 ret = -EINVAL;
320 return ret;
321 }
322
323 /*
324 * If already read at EEPROM data in module
325 * don't again read at EEPROM but there isn't file or
326 * data is NULL read EEPROM data
327 */
328 ret = fimc_is_eeprom_file_read(EEPROM_DATA_PATH, (void *)eeprom->data, EEPROM_DATA_SIZE);
329 if (ret) {
0581d52f 330 I2C_MUTEX_LOCK(eeprom->i2c_lock);
f3af0f51
WK
331 /* I2C read to Sensor EEPROM cal data */
332 ret = fimc_is_eeprom_module_read(client, EEPROM_ADD_CRC_FST, eeprom->data, EEPROM_DATA_SIZE);
333 if (ret < 0) {
334 err("%s(): eeprom i2c read failed(%d)\n", __func__, ret);
0581d52f 335 I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
f3af0f51
WK
336 return ret;
337 }
0581d52f 338 I2C_MUTEX_UNLOCK(eeprom->i2c_lock);
f3af0f51
WK
339
340 /* CRC check to each section cal data */
341 ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
342 if (ret < 0)
343 err("%s(): eeprom data invalid(%d)\n", __func__, ret);
344
345 /* Write file to Cal data */
346 ret = fimc_is_eeprom_file_write(EEPROM_DATA_PATH, (void *)eeprom->data, EEPROM_DATA_SIZE);
347 if (ret < 0) {
348 err("%s(), eeprom file write fail(%d)\n", __func__, ret);
349 return ret;
350 }
351 } else {
352 /* CRC check to each section cal data */
353 ret = CALL_EEPROMOPS(eeprom, eeprom_check_all_crc, subdev);
354 if (ret < 0)
355 err("%s(): eeprom data invalid(%d)\n", __func__, ret);
356 }
357
358 return ret;
359}
360
361static struct fimc_is_eeprom_ops sensor_eeprom_ops = {
362 .eeprom_read = fimc_is_eeprom_5e9_get_cal_data,
363 .eeprom_check_all_crc = fimc_is_eeprom_5e9_check_all_crc,
364 .eeprom_check_address = fimc_is_eeprom_5e9_check_address,
365 .eeprom_check_info = fimc_is_eeprom_5e9_check_info,
366 .eeprom_check_awb = fimc_is_eeprom_5e9_check_awb,
367 .eeprom_check_ae = fimc_is_eeprom_5e9_check_ae,
368 .eeprom_check_lsc = fimc_is_eeprom_5e9_check_lsc,
369 .eeprom_check_sfr = fimc_is_eeprom_5e9_check_sfr,
370};
371
372static int sensor_eeprom_5e9_probe(struct i2c_client *client,
373 const struct i2c_device_id *id)
374{
375 int ret = 0, i;
376 struct fimc_is_core *core;
377 struct v4l2_subdev *subdev_eeprom = NULL;
378 struct fimc_is_eeprom *eeprom = NULL;
379 struct fimc_is_device_sensor *device;
380 struct device *dev;
381 struct device_node *dnode;
382 u32 sensor_id = 0;
383
384 FIMC_BUG(!client);
385 FIMC_BUG(!fimc_is_dev);
386
387 core = (struct fimc_is_core *)dev_get_drvdata(fimc_is_dev);
388 if (!core) {
389 probe_info("core device is not yet probed");
390 return -EPROBE_DEFER;
391 }
392
393 dev = &client->dev;
394 dnode = dev->of_node;
395
396 ret = of_property_read_u32(dnode, "id", &sensor_id);
397 if (ret) {
398 probe_info("core device is not yet probed");
399 return -EPROBE_DEFER;
400 }
401
402 device = &core->sensor[sensor_id];
403 if (!device) {
404 err("sensor device is NULL");
405 ret = -ENOMEM;
406 goto p_err;
407 }
408
409 eeprom = kzalloc(sizeof(struct fimc_is_eeprom), GFP_KERNEL);
410 if (!eeprom) {
411 err("eeprom is NULL");
412 ret = -ENOMEM;
413 goto p_err;
414 }
415
416 subdev_eeprom = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
417 if (!subdev_eeprom) {
418 probe_err("subdev_cis NULL");
419 ret = -ENOMEM;
420 goto p_err;
421 }
422
423 eeprom->data = kzalloc(EEPROM_DATA_SIZE, GFP_KERNEL);
424 if (!eeprom->data) {
425 err("data is NULL");
426 ret = -ENOMEM;
427 goto p_err;
428 }
429
430 eeprom->id = EEPROM_NAME_5E9;
431 eeprom->subdev = subdev_eeprom;
432 eeprom->device = sensor_id;
433 eeprom->client = client;
434 eeprom->i2c_lock = NULL;
435 eeprom->total_size = EEPROM_DATA_SIZE;
436 eeprom->eeprom_ops = &sensor_eeprom_ops;
437
438 for (i = 0; i < CAMERA_CRC_INDEX_MAX; i++)
439 device->cal_status[i] = CRC_NO_ERROR;
440
441 device->subdev_eeprom = subdev_eeprom;
442 device->eeprom = eeprom;
443
444 v4l2_set_subdevdata(subdev_eeprom, eeprom);
445 v4l2_set_subdev_hostdata(subdev_eeprom, device);
446
447 snprintf(subdev_eeprom->name, V4L2_SUBDEV_NAME_SIZE, "eeprom-subdev.%d", eeprom->id);
448
449 probe_info("%s done\n", __func__);
450
451p_err:
452 return ret;
453}
454
455static const struct of_device_id sensor_eeprom_5e9_match[] = {
456 {
457 .compatible = "samsung,exynos5-fimc-is-sensor-eeprom-5e9",
458 },
459 {},
460};
461MODULE_DEVICE_TABLE(of, sensor_eeprom_5e9_match);
462
463static const struct i2c_device_id sensor_eeprom_5e9_idt[] = {
464 { SENSOR_EEPROM_NAME, 0 },
465 {},
466};
467
468static struct i2c_driver sensor_eeprom_5e9_driver = {
469 .probe = sensor_eeprom_5e9_probe,
470 .driver = {
471 .name = SENSOR_EEPROM_NAME,
472 .owner = THIS_MODULE,
473 .of_match_table = sensor_eeprom_5e9_match,
474 .suppress_bind_attrs = true,
475 },
476 .id_table = sensor_eeprom_5e9_idt
477};
478
479static int __init sensor_eeprom_5e9_init(void)
480{
481 int ret;
482
483 ret = i2c_add_driver(&sensor_eeprom_5e9_driver);
484 if (ret)
485 err("failed to add %s driver: %d\n",
486 sensor_eeprom_5e9_driver.driver.name, ret);
487
488 return ret;
489}
490late_initcall_sync(sensor_eeprom_5e9_init);