1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd.
3
4 #include <linux/delay.h>
5 #include <linux/i2c.h>
6 #include <linux/module.h>
7 #include <linux/pm_runtime.h>
8 #include <linux/rk-camera-module.h>
9 #include <media/v4l2-ctrls.h>
10 #include <media/v4l2-device.h>
11 #include "imx258_eeprom_head.h"
12
13 #define DEVICE_NAME "imx258_eeprom"
14
15 static inline struct imx258_eeprom_device
sd_to_imx258_eeprom(struct v4l2_subdev * subdev)16 *sd_to_imx258_eeprom(struct v4l2_subdev *subdev)
17 {
18 return container_of(subdev, struct imx258_eeprom_device, sd);
19 }
20
21 /* Read registers up to 4 at a time */
imx258_read_reg_otp(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)22 static int imx258_read_reg_otp(struct i2c_client *client, u16 reg,
23 unsigned int len, u32 *val)
24 {
25 struct i2c_msg msgs[2];
26 u8 *data_be_p;
27 __be32 data_be = 0;
28 __be16 reg_addr_be = cpu_to_be16(reg);
29 int ret;
30
31 if (len > 4 || !len)
32 return -EINVAL;
33
34 data_be_p = (u8 *)&data_be;
35 /* Write register address */
36 msgs[0].addr = client->addr;
37 msgs[0].flags = 0;
38 msgs[0].len = 2;
39 msgs[0].buf = (u8 *)®_addr_be;
40
41 /* Read data from register */
42 msgs[1].addr = client->addr;
43 msgs[1].flags = I2C_M_RD;
44 msgs[1].len = len;
45 msgs[1].buf = &data_be_p[4 - len];
46
47 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
48 if (ret != ARRAY_SIZE(msgs))
49 return -EIO;
50
51 *val = be32_to_cpu(data_be);
52
53 return 0;
54 }
55
get_vendor_flag(struct i2c_client * client)56 static u8 get_vendor_flag(struct i2c_client *client)
57 {
58 u8 vendor_flag = 0;
59
60 if (client->addr == SLAVE_ADDRESS_GZ)
61 vendor_flag |= 0x80;
62 return vendor_flag;
63 }
64
imx258_otp_read_gz(struct imx258_eeprom_device * imx258_eeprom_dev)65 static int imx258_otp_read_gz(struct imx258_eeprom_device *imx258_eeprom_dev)
66 {
67 struct i2c_client *client = imx258_eeprom_dev->client;
68 int otp_flag, i;
69 struct imx258_otp_info *otp_ptr;
70 struct device *dev = &imx258_eeprom_dev->client->dev;
71 int ret = 0;
72 u32 r_value, gr_value, gb_value, b_value;
73 u32 temp = 0;
74 u32 checksum = 0;
75
76 otp_ptr = kzalloc(sizeof(*otp_ptr), GFP_KERNEL);
77 if (!otp_ptr)
78 return -ENOMEM;
79
80 otp_flag = 0;
81 /* OTP base information*/
82 ret = imx258_read_reg_otp(client, GZ_INFO_FLAG_REG,
83 1, &otp_flag);
84 if (otp_flag == 0x01) {
85 otp_ptr->flag = 0x80; /* valid INFO in OTP */
86 ret |= imx258_read_reg_otp(client, GZ_ID_REG,
87 1, &otp_ptr->module_id);
88 ret |= imx258_read_reg_otp(client, GZ_LENS_ID_REG,
89 1, &otp_ptr->lens_id);
90 ret |= imx258_read_reg_otp(client, GZ_PRODUCT_YEAR_REG,
91 1, &otp_ptr->year);
92 ret |= imx258_read_reg_otp(client, GZ_PRODUCT_MONTH_REG,
93 1, &otp_ptr->month);
94 ret |= imx258_read_reg_otp(client, GZ_PRODUCT_DAY_REG,
95 1, &otp_ptr->day);
96 dev_dbg(dev, "fac info: module(0x%x) lens(0x%x) time(%d_%d_%d)!\n",
97 otp_ptr->module_id,
98 otp_ptr->lens_id,
99 otp_ptr->year,
100 otp_ptr->month,
101 otp_ptr->day);
102 if (ret)
103 goto err;
104 }
105
106 /* OTP WB calibration data */
107 ret = imx258_read_reg_otp(client, GZ_AWB_FLAG_REG,
108 1, &otp_flag);
109 if (otp_flag == 0x01) {
110 otp_ptr->flag |= 0x40; /* valid AWB in OTP */
111 ret |= imx258_read_reg_otp(client, GZ_CUR_R_REG,
112 1, &r_value);
113 checksum += r_value;
114 ret |= imx258_read_reg_otp(client, GZ_CUR_GR_REG,
115 1, &gr_value);
116 checksum += gr_value;
117 ret |= imx258_read_reg_otp(client, GZ_CUR_GB_REG,
118 1, &gb_value);
119 checksum += gb_value;
120 ret |= imx258_read_reg_otp(client, GZ_CUR_B_REG,
121 1, &b_value);
122 checksum += b_value;
123 otp_ptr->rg_ratio =
124 r_value * 1024 / ((gr_value + gb_value) / 2);
125 otp_ptr->bg_ratio =
126 b_value * 1024 / ((gr_value + gb_value) / 2);
127 ret |= imx258_read_reg_otp(client, GZ_GOLDEN_R_REG,
128 1, &r_value);
129 checksum += r_value;
130 ret |= imx258_read_reg_otp(client, GZ_GOLDEN_GR_REG,
131 1, &gr_value);
132 checksum += gr_value;
133 ret |= imx258_read_reg_otp(client, GZ_GOLDEN_GB_REG,
134 1, &gb_value);
135 checksum += gb_value;
136 ret |= imx258_read_reg_otp(client, GZ_GOLDEN_B_REG,
137 1, &b_value);
138 checksum += b_value;
139 otp_ptr->rg_golden =
140 r_value * 1024 / ((gr_value + gb_value) / 2);
141 otp_ptr->bg_golden =
142 b_value * 1024 / ((gr_value + gb_value) / 2);
143 ret |= imx258_read_reg_otp(client, GZ_AWB_CHECKSUM_REG,
144 1, &temp);
145 if (ret != 0 || (checksum % 0xff) != temp) {
146 dev_err(dev, "otp awb info: check sum (%d,%d),ret = %d !\n",
147 checksum,
148 temp,
149 ret);
150 goto err;
151 }
152 dev_dbg(dev, "awb cur:(rg 0x%x, bg 0x%x,)\n",
153 otp_ptr->rg_ratio, otp_ptr->bg_ratio);
154 dev_dbg(dev, "awb gol:(rg 0x%x, bg 0x%x)\n",
155 otp_ptr->rg_golden, otp_ptr->bg_golden);
156 }
157
158 checksum = 0;
159 /* OTP LSC calibration data */
160 ret = imx258_read_reg_otp(client, GZ_LSC_FLAG_REG,
161 1, &otp_flag);
162 if (otp_flag == 0x01) {
163 otp_ptr->flag |= 0x10; /* valid LSC in OTP */
164 for (i = 0; i < 504; i++) {
165 ret |= imx258_read_reg_otp(client,
166 GZ_LSC_DATA_START_REG + i,
167 1, &temp);
168 otp_ptr->lenc[i] = temp;
169 checksum += temp;
170 dev_dbg(dev,
171 "otp read lsc addr = 0x%04x, lenc[%d] = %d\n",
172 GZ_LSC_DATA_START_REG + i, i, temp);
173 }
174 ret |= imx258_read_reg_otp(client, GZ_LSC_CHECKSUM_REG,
175 1, &temp);
176 if (ret != 0 || (checksum % 0xff) != temp) {
177 dev_err(dev,
178 "otp lsc info: check sum (%d,%d),ret = %d !\n",
179 checksum, temp, ret);
180 goto err;
181 }
182 }
183
184 checksum = 0;
185 /* OTP VCM calibration data */
186 ret = imx258_read_reg_otp(client, GZ_VCM_FLAG_REG,
187 1, &otp_flag);
188 if (otp_flag == 0x01) {
189 otp_ptr->flag |= 0x20; /* valid VCM in OTP */
190 ret |= imx258_read_reg_otp(client, GZ_VCM_DIR_REG,
191 1, &otp_ptr->vcm_dir);
192 checksum += otp_ptr->vcm_dir;
193 ret |= imx258_read_reg_otp(client, GZ_VCM_START_REG,
194 1, &temp);
195 checksum += temp;
196 ret |= imx258_read_reg_otp(client, GZ_VCM_START_REG + 1,
197 1, &otp_ptr->vcm_start);
198 checksum += otp_ptr->vcm_start;
199 otp_ptr->vcm_start |= (temp << 8);
200 ret |= imx258_read_reg_otp(client, GZ_VCM_END_REG,
201 1, &temp);
202 checksum += temp;
203 ret |= imx258_read_reg_otp(client, GZ_VCM_END_REG + 1,
204 1, &otp_ptr->vcm_end);
205 checksum += otp_ptr->vcm_end;
206 otp_ptr->vcm_end |= (temp << 8);
207 ret |= imx258_read_reg_otp(client, GZ_VCM_CHECKSUM_REG,
208 1, &temp);
209 if (ret != 0 || (checksum % 0xff) != temp) {
210 dev_err(dev,
211 "otp VCM info: check sum (%d,%d),ret = %d !\n",
212 checksum, temp, ret);
213 goto err;
214 }
215 dev_dbg(dev, "vcm_info: 0x%x, 0x%x, 0x%x!\n",
216 otp_ptr->vcm_start,
217 otp_ptr->vcm_end,
218 otp_ptr->vcm_dir);
219 }
220
221 checksum = 0;
222 /* OTP SPC calibration data */
223 ret = imx258_read_reg_otp(client, GZ_SPC_FLAG_REG,
224 1, &otp_flag);
225 if (otp_flag == 0x01) {
226 otp_ptr->flag |= 0x08; /* valid LSC in OTP */
227 for (i = 0; i < 126; i++) {
228 ret |= imx258_read_reg_otp(client,
229 GZ_SPC_DATA_START_REG + i,
230 1, &temp);
231 otp_ptr->spc[i] = (uint8_t)temp;
232 checksum += temp;
233 dev_dbg(dev,
234 "otp read spc addr = 0x%04x, spc[%d] = %d\n",
235 GZ_SPC_DATA_START_REG + i, i, temp);
236 }
237 ret |= imx258_read_reg_otp(client, GZ_SPC_CHECKSUM_REG,
238 1, &temp);
239 if (ret != 0 || (checksum % 0xff) != temp) {
240 dev_err(dev,
241 "otp spc info: check sum (%d,%d),ret = %d !\n",
242 checksum, temp, ret);
243 goto err;
244 }
245 }
246
247 if (otp_ptr->flag) {
248 imx258_eeprom_dev->otp = otp_ptr;
249 } else {
250 imx258_eeprom_dev->otp = NULL;
251 kfree(otp_ptr);
252 }
253
254 return 0;
255 err:
256 imx258_eeprom_dev->otp = NULL;
257 kfree(otp_ptr);
258 return -EINVAL;
259 }
260
imx258_otp_read(struct imx258_eeprom_device * imx258_eeprom_dev)261 static int imx258_otp_read(struct imx258_eeprom_device *imx258_eeprom_dev)
262 {
263 u8 vendor_flag = 0;
264 struct i2c_client *client = imx258_eeprom_dev->client;
265
266 vendor_flag = get_vendor_flag(client);
267 if (vendor_flag == 0x80)
268 imx258_otp_read_gz(imx258_eeprom_dev);
269 return 0;
270 }
271
imx258_eeprom_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)272 static long imx258_eeprom_ioctl(struct v4l2_subdev *sd,
273 unsigned int cmd, void *arg)
274 {
275 struct imx258_eeprom_device *imx258_eeprom_dev =
276 sd_to_imx258_eeprom(sd);
277 imx258_otp_read(imx258_eeprom_dev);
278 if (arg && imx258_eeprom_dev->otp)
279 memcpy(arg, imx258_eeprom_dev->otp,
280 sizeof(struct imx258_otp_info));
281 return 0;
282 }
283
284 static const struct v4l2_subdev_core_ops imx258_eeprom_core_ops = {
285 .ioctl = imx258_eeprom_ioctl,
286 };
287
288 static const struct v4l2_subdev_ops imx258_eeprom_ops = {
289 .core = &imx258_eeprom_core_ops,
290 };
291
imx258_eeprom_subdev_cleanup(struct imx258_eeprom_device * dev)292 static void imx258_eeprom_subdev_cleanup(struct imx258_eeprom_device *dev)
293 {
294 v4l2_device_unregister_subdev(&dev->sd);
295 media_entity_cleanup(&dev->sd.entity);
296 }
297
imx258_eeprom_probe(struct i2c_client * client,const struct i2c_device_id * id)298 static int imx258_eeprom_probe(struct i2c_client *client,
299 const struct i2c_device_id *id)
300 {
301 struct imx258_eeprom_device *imx258_eeprom_dev;
302
303 dev_info(&client->dev, "probing...\n");
304 imx258_eeprom_dev = devm_kzalloc(&client->dev,
305 sizeof(*imx258_eeprom_dev),
306 GFP_KERNEL);
307
308 if (imx258_eeprom_dev == NULL) {
309 dev_err(&client->dev, "Probe failed\n");
310 return -ENOMEM;
311 }
312 v4l2_i2c_subdev_init(&imx258_eeprom_dev->sd,
313 client, &imx258_eeprom_ops);
314 imx258_eeprom_dev->client = client;
315 pm_runtime_set_active(&client->dev);
316 pm_runtime_enable(&client->dev);
317 pm_runtime_idle(&client->dev);
318
319 dev_info(&client->dev, "probing successful\n");
320
321 return 0;
322 }
323
imx258_eeprom_remove(struct i2c_client * client)324 static int imx258_eeprom_remove(struct i2c_client *client)
325 {
326 struct v4l2_subdev *sd = i2c_get_clientdata(client);
327 struct imx258_eeprom_device *imx258_eeprom_dev =
328 sd_to_imx258_eeprom(sd);
329 kfree(imx258_eeprom_dev->otp);
330 pm_runtime_disable(&client->dev);
331 imx258_eeprom_subdev_cleanup(imx258_eeprom_dev);
332
333 return 0;
334 }
335
imx258_eeprom_suspend(struct device * dev)336 static int __maybe_unused imx258_eeprom_suspend(struct device *dev)
337 {
338 return 0;
339 }
340
imx258_eeprom_resume(struct device * dev)341 static int __maybe_unused imx258_eeprom_resume(struct device *dev)
342 {
343 return 0;
344 }
345
346 static const struct i2c_device_id imx258_eeprom_id_table[] = {
347 { DEVICE_NAME, 0 },
348 { { 0 } }
349 };
350 MODULE_DEVICE_TABLE(i2c, imx258_eeprom_id_table);
351
352 static const struct of_device_id imx258_eeprom_of_table[] = {
353 { .compatible = "sony,imx258_eeprom" },
354 { { 0 } }
355 };
356 MODULE_DEVICE_TABLE(of, imx258_eeprom_of_table);
357
358 static const struct dev_pm_ops imx258_eeprom_pm_ops = {
359 SET_SYSTEM_SLEEP_PM_OPS(imx258_eeprom_suspend, imx258_eeprom_resume)
360 SET_RUNTIME_PM_OPS(imx258_eeprom_suspend, imx258_eeprom_resume, NULL)
361 };
362
363 static struct i2c_driver imx258_eeprom_i2c_driver = {
364 .driver = {
365 .name = DEVICE_NAME,
366 .pm = &imx258_eeprom_pm_ops,
367 .of_match_table = imx258_eeprom_of_table,
368 },
369 .probe = &imx258_eeprom_probe,
370 .remove = &imx258_eeprom_remove,
371 .id_table = imx258_eeprom_id_table,
372 };
373
374 module_i2c_driver(imx258_eeprom_i2c_driver);
375
376 MODULE_DESCRIPTION("IMX258 OTP driver");
377 MODULE_LICENSE("GPL v2");
378