1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/media/i2c/ccs/ccs-reg-access.c
5 * Generic driver for MIPI CCS/SMIA/SMIA++ compliant camera sensors
7 * Copyright (C) 2020 Intel Corporation
8 * Copyright (C) 2011--2012 Nokia Corporation
9 * Contact: Sakari Ailus <sakari.ailus@linux.intel.com>
12 #include <linux/unaligned.h>
14 #include <linux/delay.h>
15 #include <linux/i2c.h>
18 #include "ccs-limits.h"
20 static u32
float_to_u32_mul_1000000(struct i2c_client
*client
, u32 phloat
)
25 if (phloat
>= 0x80000000) {
26 dev_err(&client
->dev
, "this is a negative number\n");
30 if (phloat
== 0x7f800000)
33 if ((phloat
& 0x7f800000) == 0x7f800000) {
34 dev_err(&client
->dev
, "NaN or other special number\n");
38 /* Valid cases begin here */
40 return 0; /* Valid zero */
42 if (phloat
> 0x4f800000)
43 return ~0; /* larger than 4294967295 */
46 * Unbias exponent (note how phloat is now guaranteed to
47 * have 0 in the high bit)
49 exp
= ((int32_t)phloat
>> 23) - 127;
51 /* Extract mantissa, add missing '1' bit and it's in MHz */
52 man
= ((phloat
& 0x7fffff) | 0x800000) * 1000000ULL;
59 man
>>= 23; /* Remove mantissa bias */
61 return man
& 0xffffffff;
65 static u32
ireal32_to_u32_mul_1000000(struct i2c_client
*client
, u32 val
)
67 if (val
>> 10 > U32_MAX
/ 15625) {
68 dev_warn(&client
->dev
, "value %u overflows!\n", val
);
72 return ((val
>> 10) * 15625) +
73 (val
& GENMASK(9, 0)) * 15625 / 1024;
76 u32
ccs_reg_conv(struct ccs_sensor
*sensor
, u32 reg
, u32 val
)
78 struct i2c_client
*client
= v4l2_get_subdevdata(&sensor
->src
->sd
);
80 if (reg
& CCS_FL_FLOAT_IREAL
) {
81 if (CCS_LIM(sensor
, CLOCK_CAPA_TYPE_CAPABILITY
) &
82 CCS_CLOCK_CAPA_TYPE_CAPABILITY_IREAL
)
83 val
= ireal32_to_u32_mul_1000000(client
, val
);
85 val
= float_to_u32_mul_1000000(client
, val
);
86 } else if (reg
& CCS_FL_IREAL
) {
87 val
= ireal32_to_u32_mul_1000000(client
, val
);
94 * Read a 8/16/32-bit i2c register. The value is returned in 'val'.
95 * Returns zero if successful, or non-zero otherwise.
97 static int __ccs_read_addr(struct ccs_sensor
*sensor
, u32 reg
, u32
*val
,
98 bool only8
, bool conv
)
103 rval
= cci_read(sensor
->regmap
, reg
, &__val
, NULL
);
107 *val
= conv
? ccs_reg_conv(sensor
, reg
, __val
) : __val
;
112 static int __ccs_static_data_read_ro_reg(struct ccs_reg
*regs
, size_t num_regs
,
115 unsigned int width
= CCI_REG_WIDTH_BYTES(reg
);
118 for (i
= 0; i
< num_regs
; i
++, regs
++) {
121 if (regs
->addr
+ regs
->len
< CCS_REG_ADDR(reg
) + width
)
124 if (regs
->addr
> CCS_REG_ADDR(reg
))
127 data
= ®s
->value
[CCS_REG_ADDR(reg
) - regs
->addr
];
134 *val
= get_unaligned_be16(data
);
137 *val
= get_unaligned_be32(data
);
151 ccs_static_data_read_ro_reg(struct ccs_sensor
*sensor
, u32 reg
, u32
*val
)
153 if (!__ccs_static_data_read_ro_reg(sensor
->sdata
.sensor_read_only_regs
,
154 sensor
->sdata
.num_sensor_read_only_regs
,
158 return __ccs_static_data_read_ro_reg(sensor
->mdata
.module_read_only_regs
,
159 sensor
->mdata
.num_module_read_only_regs
,
163 static int ccs_read_addr_raw(struct ccs_sensor
*sensor
, u32 reg
, u32
*val
,
164 bool force8
, bool quirk
, bool conv
, bool data
)
169 rval
= ccs_static_data_read_ro_reg(sensor
, reg
, val
);
176 rval
= ccs_call_quirk(sensor
, reg_access
, false, ®
, val
);
177 if (rval
== -ENOIOCTLCMD
)
183 return __ccs_read_addr(sensor
, reg
, val
, true, conv
);
186 return __ccs_read_addr(sensor
, reg
, val
,
187 ccs_needs_quirk(sensor
,
188 CCS_QUIRK_FLAG_8BIT_READ_ONLY
),
192 int ccs_read_addr(struct ccs_sensor
*sensor
, u32 reg
, u32
*val
)
194 return ccs_read_addr_raw(sensor
, reg
, val
, false, true, true, true);
197 int ccs_read_addr_8only(struct ccs_sensor
*sensor
, u32 reg
, u32
*val
)
199 return ccs_read_addr_raw(sensor
, reg
, val
, true, true, true, true);
202 int ccs_read_addr_noconv(struct ccs_sensor
*sensor
, u32 reg
, u32
*val
)
204 return ccs_read_addr_raw(sensor
, reg
, val
, false, true, false, true);
208 * Write to a 8/16-bit register.
209 * Returns zero if successful, or non-zero otherwise.
211 int ccs_write_addr(struct ccs_sensor
*sensor
, u32 reg
, u32 val
)
213 unsigned int retries
= 10;
216 rval
= ccs_call_quirk(sensor
, reg_access
, true, ®
, &val
);
217 if (rval
== -ENOIOCTLCMD
)
224 if (cci_write(sensor
->regmap
, reg
, val
, &rval
))
226 } while (rval
&& --retries
);
231 #define MAX_WRITE_LEN 32U
233 int ccs_write_data_regs(struct ccs_sensor
*sensor
, struct ccs_reg
*regs
,
236 struct i2c_client
*client
= v4l2_get_subdevdata(&sensor
->src
->sd
);
239 for (i
= 0; i
< num_regs
; i
++, regs
++) {
240 unsigned char *regdata
= regs
->value
;
244 for (j
= 0; j
< regs
->len
; j
+= len
, regdata
+= len
) {
245 char printbuf
[(MAX_WRITE_LEN
<< 1) +
247 unsigned int retries
= 10;
250 len
= min(regs
->len
- j
, MAX_WRITE_LEN
);
252 bin2hex(printbuf
, regdata
, len
);
253 dev_dbg(&client
->dev
,
254 "writing msr reg 0x%4.4x value 0x%s\n",
255 regs
->addr
+ j
, printbuf
);
258 rval
= regmap_bulk_write(sensor
->regmap
,
263 } while (rval
&& --retries
);
266 dev_err(&client
->dev
,
267 "error writing %u octets to address 0x%4.4x\n",
268 len
, regs
->addr
+ j
);