xref: /linux/drivers/media/i2c/ccs/ccs-reg-access.c (revision a6021aa24f6417416d93318bbfa022ab229c33c8)
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 <sakari.ailus@linux.intel.com>
10  */
11 
12 #include <linux/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 u32 float_to_u32_mul_1000000(struct i2c_client *client, u32 phloat)
21 {
22 	s32 exp;
23 	u64 man;
24 
25 	if (phloat >= 0x80000000) {
26 		dev_err(&client->dev, "this is a negative number\n");
27 		return 0;
28 	}
29 
30 	if (phloat == 0x7f800000)
31 		return ~0; /* Inf. */
32 
33 	if ((phloat & 0x7f800000) == 0x7f800000) {
34 		dev_err(&client->dev, "NaN or other special number\n");
35 		return 0;
36 	}
37 
38 	/* Valid cases begin here */
39 	if (phloat == 0)
40 		return 0; /* Valid zero */
41 
42 	if (phloat > 0x4f800000)
43 		return ~0; /* larger than 4294967295 */
44 
45 	/*
46 	 * Unbias exponent (note how phloat is now guaranteed to
47 	 * have 0 in the high bit)
48 	 */
49 	exp = ((int32_t)phloat >> 23) - 127;
50 
51 	/* Extract mantissa, add missing '1' bit and it's in MHz */
52 	man = ((phloat & 0x7fffff) | 0x800000) * 1000000ULL;
53 
54 	if (exp < 0)
55 		man >>= -exp;
56 	else
57 		man <<= exp;
58 
59 	man >>= 23; /* Remove mantissa bias */
60 
61 	return man & 0xffffffff;
62 }
63 
64 
65 static u32 ireal32_to_u32_mul_1000000(struct i2c_client *client, u32 val)
66 {
67 	if (val >> 10 > U32_MAX / 15625) {
68 		dev_warn(&client->dev, "value %u overflows!\n", val);
69 		return U32_MAX;
70 	}
71 
72 	return ((val >> 10) * 15625) +
73 		(val & GENMASK(9, 0)) * 15625 / 1024;
74 }
75 
76 u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val)
77 {
78 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
79 
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);
84 		else
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);
88 	}
89 
90 	return val;
91 }
92 
93 /*
94  * Read a 8/16/32-bit i2c register.  The value is returned in 'val'.
95  * Returns zero if successful, or non-zero otherwise.
96  */
97 static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val,
98 			   bool only8, bool conv)
99 {
100 	u64 __val;
101 	int rval;
102 
103 	rval = cci_read(sensor->regmap, reg, &__val, NULL);
104 	if (rval < 0)
105 		return rval;
106 
107 	*val = conv ? ccs_reg_conv(sensor, reg, __val) : __val;
108 
109 	return 0;
110 }
111 
112 static int __ccs_static_data_read_ro_reg(struct ccs_reg *regs, size_t num_regs,
113 					 u32 reg, u32 *val)
114 {
115 	unsigned int width = CCI_REG_WIDTH_BYTES(reg);
116 	size_t i;
117 
118 	for (i = 0; i < num_regs; i++, regs++) {
119 		u8 *data;
120 
121 		if (regs->addr + regs->len < CCS_REG_ADDR(reg) + width)
122 			continue;
123 
124 		if (regs->addr > CCS_REG_ADDR(reg))
125 			break;
126 
127 		data = &regs->value[CCS_REG_ADDR(reg) - regs->addr];
128 
129 		switch (width) {
130 		case sizeof(u8):
131 			*val = *data;
132 			break;
133 		case sizeof(u16):
134 			*val = get_unaligned_be16(data);
135 			break;
136 		case sizeof(u32):
137 			*val = get_unaligned_be32(data);
138 			break;
139 		default:
140 			WARN_ON(1);
141 			return -EINVAL;
142 		}
143 
144 		return 0;
145 	}
146 
147 	return -ENOENT;
148 }
149 
150 static int
151 ccs_static_data_read_ro_reg(struct ccs_sensor *sensor, u32 reg, u32 *val)
152 {
153 	if (!__ccs_static_data_read_ro_reg(sensor->sdata.sensor_read_only_regs,
154 					   sensor->sdata.num_sensor_read_only_regs,
155 					   reg, val))
156 		return 0;
157 
158 	return __ccs_static_data_read_ro_reg(sensor->mdata.module_read_only_regs,
159 					     sensor->mdata.num_module_read_only_regs,
160 					     reg, val);
161 }
162 
163 static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val,
164 			     bool force8, bool quirk, bool conv, bool data)
165 {
166 	int rval;
167 
168 	if (data) {
169 		rval = ccs_static_data_read_ro_reg(sensor, reg, val);
170 		if (!rval)
171 			return 0;
172 	}
173 
174 	if (quirk) {
175 		*val = 0;
176 		rval = ccs_call_quirk(sensor, reg_access, false, &reg, val);
177 		if (rval == -ENOIOCTLCMD)
178 			return 0;
179 		if (rval < 0)
180 			return rval;
181 
182 		if (force8)
183 			return __ccs_read_addr(sensor, reg, val, true, conv);
184 	}
185 
186 	return __ccs_read_addr(sensor, reg, val,
187 			       ccs_needs_quirk(sensor,
188 					       CCS_QUIRK_FLAG_8BIT_READ_ONLY),
189 			       conv);
190 }
191 
192 int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val)
193 {
194 	return ccs_read_addr_raw(sensor, reg, val, false, true, true, true);
195 }
196 
197 int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val)
198 {
199 	return ccs_read_addr_raw(sensor, reg, val, true, true, true, true);
200 }
201 
202 int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val)
203 {
204 	return ccs_read_addr_raw(sensor, reg, val, false, true, false, true);
205 }
206 
207 /*
208  * Write to a 8/16-bit register.
209  * Returns zero if successful, or non-zero otherwise.
210  */
211 int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val)
212 {
213 	unsigned int retries = 10;
214 	int rval;
215 
216 	rval = ccs_call_quirk(sensor, reg_access, true, &reg, &val);
217 	if (rval == -ENOIOCTLCMD)
218 		return 0;
219 	if (rval < 0)
220 		return rval;
221 
222 	rval = 0;
223 	do {
224 		if (cci_write(sensor->regmap, reg, val, &rval))
225 			fsleep(1000);
226 	} while (rval && --retries);
227 
228 	return rval;
229 }
230 
231 #define MAX_WRITE_LEN	32U
232 
233 int ccs_write_data_regs(struct ccs_sensor *sensor, struct ccs_reg *regs,
234 			size_t num_regs)
235 {
236 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
237 	size_t i;
238 
239 	for (i = 0; i < num_regs; i++, regs++) {
240 		unsigned char *regdata = regs->value;
241 		unsigned int j;
242 		int len;
243 
244 		for (j = 0; j < regs->len; j += len, regdata += len) {
245 			char printbuf[(MAX_WRITE_LEN << 1) +
246 				      1 /* \0 */] = { 0 };
247 			unsigned int retries = 10;
248 			int rval;
249 
250 			len = min(regs->len - j, MAX_WRITE_LEN);
251 
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);
256 
257 			do {
258 				rval = regmap_bulk_write(sensor->regmap,
259 							 regs->addr + j,
260 							 regdata, len);
261 				if (rval)
262 					fsleep(1000);
263 			} while (rval && --retries);
264 
265 			if (rval) {
266 				dev_err(&client->dev,
267 					"error writing %u octets to address 0x%4.4x\n",
268 					len, regs->addr + j);
269 				return rval;
270 			}
271 		}
272 	}
273 
274 	return 0;
275 }
276