]> Git Repo - J-linux.git/blob - drivers/media/i2c/ccs/ccs-reg-access.c
media: ccs: Print written register values
[J-linux.git] / drivers / media / i2c / ccs / ccs-reg-access.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * drivers/media/i2c/ccs/ccs-reg-access.c
4  *
5  * Generic driver for MIPI CCS/SMIA/SMIA++ compliant camera sensors
6  *
7  * Copyright (C) 2020 Intel Corporation
8  * Copyright (C) 2011--2012 Nokia Corporation
9  * Contact: Sakari Ailus <[email protected]>
10  */
11
12 #include <asm/unaligned.h>
13
14 #include <linux/delay.h>
15 #include <linux/i2c.h>
16
17 #include "ccs.h"
18 #include "ccs-limits.h"
19
20 static uint32_t float_to_u32_mul_1000000(struct i2c_client *client,
21                                          uint32_t phloat)
22 {
23         int32_t exp;
24         uint64_t man;
25
26         if (phloat >= 0x80000000) {
27                 dev_err(&client->dev, "this is a negative number\n");
28                 return 0;
29         }
30
31         if (phloat == 0x7f800000)
32                 return ~0; /* Inf. */
33
34         if ((phloat & 0x7f800000) == 0x7f800000) {
35                 dev_err(&client->dev, "NaN or other special number\n");
36                 return 0;
37         }
38
39         /* Valid cases begin here */
40         if (phloat == 0)
41                 return 0; /* Valid zero */
42
43         if (phloat > 0x4f800000)
44                 return ~0; /* larger than 4294967295 */
45
46         /*
47          * Unbias exponent (note how phloat is now guaranteed to
48          * have 0 in the high bit)
49          */
50         exp = ((int32_t)phloat >> 23) - 127;
51
52         /* Extract mantissa, add missing '1' bit and it's in MHz */
53         man = ((phloat & 0x7fffff) | 0x800000) * 1000000ULL;
54
55         if (exp < 0)
56                 man >>= -exp;
57         else
58                 man <<= exp;
59
60         man >>= 23; /* Remove mantissa bias */
61
62         return man & 0xffffffff;
63 }
64
65
66 /*
67  * Read a 8/16/32-bit i2c register.  The value is returned in 'val'.
68  * Returns zero if successful, or non-zero otherwise.
69  */
70 static int ____ccs_read_addr(struct ccs_sensor *sensor, u16 reg, u16 len,
71                              u32 *val)
72 {
73         struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
74         struct i2c_msg msg;
75         unsigned char data_buf[sizeof(u32)] = { 0 };
76         unsigned char offset_buf[sizeof(u16)];
77         int r;
78
79         if (len > sizeof(data_buf))
80                 return -EINVAL;
81
82         msg.addr = client->addr;
83         msg.flags = 0;
84         msg.len = sizeof(offset_buf);
85         msg.buf = offset_buf;
86         put_unaligned_be16(reg, offset_buf);
87
88         r = i2c_transfer(client->adapter, &msg, 1);
89         if (r != 1) {
90                 if (r >= 0)
91                         r = -EBUSY;
92                 goto err;
93         }
94
95         msg.len = len;
96         msg.flags = I2C_M_RD;
97         msg.buf = &data_buf[sizeof(data_buf) - len];
98
99         r = i2c_transfer(client->adapter, &msg, 1);
100         if (r != 1) {
101                 if (r >= 0)
102                         r = -EBUSY;
103                 goto err;
104         }
105
106         *val = get_unaligned_be32(data_buf);
107
108         return 0;
109
110 err:
111         dev_err(&client->dev, "read from offset 0x%x error %d\n", reg, r);
112
113         return r;
114 }
115
116 /* Read a register using 8-bit access only. */
117 static int ____ccs_read_addr_8only(struct ccs_sensor *sensor, u16 reg,
118                                    u16 len, u32 *val)
119 {
120         unsigned int i;
121         int rval;
122
123         *val = 0;
124
125         for (i = 0; i < len; i++) {
126                 u32 val8;
127
128                 rval = ____ccs_read_addr(sensor, reg + i, 1, &val8);
129                 if (rval < 0)
130                         return rval;
131                 *val |= val8 << ((len - i - 1) << 3);
132         }
133
134         return 0;
135 }
136
137 unsigned int ccs_reg_width(u32 reg)
138 {
139         if (reg & CCS_FL_16BIT)
140                 return sizeof(uint16_t);
141         if (reg & CCS_FL_32BIT)
142                 return sizeof(uint32_t);
143
144         return sizeof(uint8_t);
145 }
146
147 static u32 ireal32_to_u32_mul_1000000(struct i2c_client *client, u32 val)
148 {
149         if (val >> 10 > U32_MAX / 15625) {
150                 dev_warn(&client->dev, "value %u overflows!\n", val);
151                 return U32_MAX;
152         }
153
154         return ((val >> 10) * 15625) +
155                 (val & GENMASK(9, 0)) * 15625 / 1024;
156 }
157
158 u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val)
159 {
160         struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
161
162         if (reg & CCS_FL_FLOAT_IREAL) {
163                 if (CCS_LIM(sensor, CLOCK_CAPA_TYPE_CAPABILITY) &
164                     CCS_CLOCK_CAPA_TYPE_CAPABILITY_IREAL)
165                         val = ireal32_to_u32_mul_1000000(client, val);
166                 else
167                         val = float_to_u32_mul_1000000(client, val);
168         } else if (reg & CCS_FL_IREAL) {
169                 val = ireal32_to_u32_mul_1000000(client, val);
170         }
171
172         return val;
173 }
174
175 /*
176  * Read a 8/16/32-bit i2c register.  The value is returned in 'val'.
177  * Returns zero if successful, or non-zero otherwise.
178  */
179 static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val,
180                            bool only8, bool conv)
181 {
182         unsigned int len = ccs_reg_width(reg);
183         int rval;
184
185         if (!only8)
186                 rval = ____ccs_read_addr(sensor, CCS_REG_ADDR(reg), len, val);
187         else
188                 rval = ____ccs_read_addr_8only(sensor, CCS_REG_ADDR(reg), len,
189                                                val);
190         if (rval < 0)
191                 return rval;
192
193         if (!conv)
194                 return 0;
195
196         *val = ccs_reg_conv(sensor, reg, *val);
197
198         return 0;
199 }
200
201 static int __ccs_read_data(struct ccs_reg *regs, size_t num_regs,
202                            u32 reg, u32 *val)
203 {
204         unsigned int width = ccs_reg_width(reg);
205         size_t i;
206
207         for (i = 0; i < num_regs; i++, regs++) {
208                 uint8_t *data;
209
210                 if (regs->addr + regs->len < CCS_REG_ADDR(reg) + width)
211                         continue;
212
213                 if (regs->addr > CCS_REG_ADDR(reg))
214                         break;
215
216                 data = &regs->value[CCS_REG_ADDR(reg) - regs->addr];
217
218                 switch (width) {
219                 case sizeof(uint8_t):
220                         *val = *data;
221                         break;
222                 case sizeof(uint16_t):
223                         *val = get_unaligned_be16(data);
224                         break;
225                 case sizeof(uint32_t):
226                         *val = get_unaligned_be32(data);
227                         break;
228                 default:
229                         WARN_ON(1);
230                         return -EINVAL;
231                 }
232
233                 return 0;
234         }
235
236         return -ENOENT;
237 }
238
239 static int ccs_read_data(struct ccs_sensor *sensor, u32 reg, u32 *val)
240 {
241         if (!__ccs_read_data(sensor->sdata.sensor_read_only_regs,
242                              sensor->sdata.num_sensor_read_only_regs,
243                              reg, val))
244                 return 0;
245
246         return __ccs_read_data(sensor->mdata.module_read_only_regs,
247                                sensor->mdata.num_module_read_only_regs,
248                                reg, val);
249 }
250
251 static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val,
252                              bool force8, bool quirk, bool conv, bool data)
253 {
254         int rval;
255
256         if (data) {
257                 rval = ccs_read_data(sensor, reg, val);
258                 if (!rval)
259                         return 0;
260         }
261
262         if (quirk) {
263                 *val = 0;
264                 rval = ccs_call_quirk(sensor, reg_access, false, &reg, val);
265                 if (rval == -ENOIOCTLCMD)
266                         return 0;
267                 if (rval < 0)
268                         return rval;
269
270                 if (force8)
271                         return __ccs_read_addr(sensor, reg, val, true, conv);
272         }
273
274         return __ccs_read_addr(sensor, reg, val,
275                                ccs_needs_quirk(sensor,
276                                                CCS_QUIRK_FLAG_8BIT_READ_ONLY),
277                                conv);
278 }
279
280 int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val)
281 {
282         return ccs_read_addr_raw(sensor, reg, val, false, true, true, true);
283 }
284
285 int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val)
286 {
287         return ccs_read_addr_raw(sensor, reg, val, true, true, true, true);
288 }
289
290 int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val)
291 {
292         return ccs_read_addr_raw(sensor, reg, val, false, true, false, true);
293 }
294
295 static int ccs_write_retry(struct i2c_client *client, struct i2c_msg *msg)
296 {
297         unsigned int retries;
298         int r;
299
300         for (retries = 0; retries < 10; retries++) {
301                 /*
302                  * Due to unknown reason sensor stops responding. This
303                  * loop is a temporaty solution until the root cause
304                  * is found.
305                  */
306                 r = i2c_transfer(client->adapter, msg, 1);
307                 if (r != 1) {
308                         usleep_range(1000, 2000);
309                         continue;
310                 }
311
312                 if (retries)
313                         dev_err(&client->dev,
314                                 "sensor i2c stall encountered. retries: %d\n",
315                                 retries);
316                 return 0;
317         }
318
319         return r;
320 }
321
322 int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val)
323 {
324         struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
325         struct i2c_msg msg;
326         unsigned char data[6];
327         unsigned int len = ccs_reg_width(reg);
328         int r;
329
330         if (len > sizeof(data) - 2)
331                 return -EINVAL;
332
333         msg.addr = client->addr;
334         msg.flags = 0; /* Write */
335         msg.len = 2 + len;
336         msg.buf = data;
337
338         put_unaligned_be16(CCS_REG_ADDR(reg), data);
339         put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2);
340
341         dev_dbg(&client->dev, "writing reg 0x%4.4x value 0x%*.*x (%u)\n",
342                 CCS_REG_ADDR(reg), ccs_reg_width(reg) << 1,
343                 ccs_reg_width(reg) << 1, val, val);
344
345         r = ccs_write_retry(client, &msg);
346         if (r)
347                 dev_err(&client->dev,
348                         "wrote 0x%x to offset 0x%x error %d\n", val,
349                         CCS_REG_ADDR(reg), r);
350
351         return r;
352 }
353
354 /*
355  * Write to a 8/16-bit register.
356  * Returns zero if successful, or non-zero otherwise.
357  */
358 int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val)
359 {
360         int rval;
361
362         rval = ccs_call_quirk(sensor, reg_access, true, &reg, &val);
363         if (rval == -ENOIOCTLCMD)
364                 return 0;
365         if (rval < 0)
366                 return rval;
367
368         return ccs_write_addr_no_quirk(sensor, reg, val);
369 }
370
371 #define MAX_WRITE_LEN   32U
372
373 int ccs_write_data_regs(struct ccs_sensor *sensor, struct ccs_reg *regs,
374                         size_t num_regs)
375 {
376         struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
377         unsigned char buf[2 + MAX_WRITE_LEN];
378         struct i2c_msg msg = {
379                 .addr = client->addr,
380                 .buf = buf,
381         };
382         size_t i;
383
384         for (i = 0; i < num_regs; i++, regs++) {
385                 unsigned char *regdata = regs->value;
386                 unsigned int j;
387
388                 for (j = 0; j < regs->len;
389                      j += msg.len - 2, regdata += msg.len - 2) {
390                         int rval;
391
392                         msg.len = min(regs->len - j, MAX_WRITE_LEN);
393
394                         put_unaligned_be16(regs->addr + j, buf);
395                         memcpy(buf + 2, regdata, msg.len);
396                         msg.len += 2;
397
398                         rval = ccs_write_retry(client, &msg);
399                         if (rval) {
400                                 dev_err(&client->dev,
401                                         "error writing %u octets to address 0x%4.4x\n",
402                                         msg.len, regs->addr + j);
403                                 return rval;
404                         }
405                 }
406         }
407
408         return 0;
409 }
This page took 0.057837 seconds and 4 git commands to generate.