hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/i2c/smiapp/smiapp-regs.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * drivers/media/i2c/smiapp/smiapp-regs.c
34 *
....@@ -5,16 +6,9 @@
56 *
67 * Copyright (C) 2011--2012 Nokia Corporation
78 * Contact: Sakari Ailus <sakari.ailus@iki.fi>
8
- *
9
- * This program is free software; you can redistribute it and/or
10
- * modify it under the terms of the GNU General Public License
11
- * version 2 as published by the Free Software Foundation.
12
- *
13
- * This program is distributed in the hope that it will be useful, but
14
- * WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
- * General Public License for more details.
179 */
10
+
11
+#include <asm/unaligned.h>
1812
1913 #include <linux/delay.h>
2014 #include <linux/i2c.h>
....@@ -77,18 +71,19 @@
7771 {
7872 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
7973 struct i2c_msg msg;
80
- unsigned char data[4];
81
- u16 offset = reg;
74
+ unsigned char data_buf[sizeof(u32)] = { 0 };
75
+ unsigned char offset_buf[sizeof(u16)];
8276 int r;
77
+
78
+ if (len > sizeof(data_buf))
79
+ return -EINVAL;
8380
8481 msg.addr = client->addr;
8582 msg.flags = 0;
86
- msg.len = 2;
87
- msg.buf = data;
83
+ msg.len = sizeof(offset_buf);
84
+ msg.buf = offset_buf;
85
+ put_unaligned_be16(reg, offset_buf);
8886
89
- /* high byte goes out first */
90
- data[0] = (u8) (offset >> 8);
91
- data[1] = (u8) offset;
9287 r = i2c_transfer(client->adapter, &msg, 1);
9388 if (r != 1) {
9489 if (r >= 0)
....@@ -98,6 +93,8 @@
9893
9994 msg.len = len;
10095 msg.flags = I2C_M_RD;
96
+ msg.buf = &data_buf[sizeof(data_buf) - len];
97
+
10198 r = i2c_transfer(client->adapter, &msg, 1);
10299 if (r != 1) {
103100 if (r >= 0)
....@@ -105,27 +102,12 @@
105102 goto err;
106103 }
107104
108
- *val = 0;
109
- /* high byte comes first */
110
- switch (len) {
111
- case SMIAPP_REG_32BIT:
112
- *val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) +
113
- data[3];
114
- break;
115
- case SMIAPP_REG_16BIT:
116
- *val = (data[0] << 8) + data[1];
117
- break;
118
- case SMIAPP_REG_8BIT:
119
- *val = data[0];
120
- break;
121
- default:
122
- BUG();
123
- }
105
+ *val = get_unaligned_be32(data_buf);
124106
125107 return 0;
126108
127109 err:
128
- dev_err(&client->dev, "read from offset 0x%x error %d\n", offset, r);
110
+ dev_err(&client->dev, "read from offset 0x%x error %d\n", reg, r);
129111
130112 return r;
131113 }
....@@ -166,7 +148,7 @@
166148 && len != SMIAPP_REG_32BIT)
167149 return -EINVAL;
168150
169
- if (len == SMIAPP_REG_8BIT || !only8)
151
+ if (!only8)
170152 rval = ____smiapp_read(sensor, SMIAPP_REG_ADDR(reg), len, val);
171153 else
172154 rval = ____smiapp_read_8only(sensor, SMIAPP_REG_ADDR(reg), len,
....@@ -222,44 +204,19 @@
222204 struct i2c_msg msg;
223205 unsigned char data[6];
224206 unsigned int retries;
225
- u8 flags = SMIAPP_REG_FLAGS(reg);
226207 u8 len = SMIAPP_REG_WIDTH(reg);
227
- u16 offset = SMIAPP_REG_ADDR(reg);
228208 int r;
229209
230
- if ((len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT &&
231
- len != SMIAPP_REG_32BIT) || flags)
210
+ if (len > sizeof(data) - 2)
232211 return -EINVAL;
233
-
234
- if (!sensor->active)
235
- return 0;
236212
237213 msg.addr = client->addr;
238214 msg.flags = 0; /* Write */
239215 msg.len = 2 + len;
240216 msg.buf = data;
241217
242
- /* high byte goes out first */
243
- data[0] = (u8) (reg >> 8);
244
- data[1] = (u8) (reg & 0xff);
245
-
246
- switch (len) {
247
- case SMIAPP_REG_8BIT:
248
- data[2] = val;
249
- break;
250
- case SMIAPP_REG_16BIT:
251
- data[2] = val >> 8;
252
- data[3] = val;
253
- break;
254
- case SMIAPP_REG_32BIT:
255
- data[2] = val >> 24;
256
- data[3] = val >> 16;
257
- data[4] = val >> 8;
258
- data[5] = val;
259
- break;
260
- default:
261
- BUG();
262
- }
218
+ put_unaligned_be16(SMIAPP_REG_ADDR(reg), data);
219
+ put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2);
263220
264221 for (retries = 0; retries < 5; retries++) {
265222 /*
....@@ -280,7 +237,8 @@
280237 }
281238
282239 dev_err(&client->dev,
283
- "wrote 0x%x to offset 0x%x error %d\n", val, offset, r);
240
+ "wrote 0x%x to offset 0x%x error %d\n", val,
241
+ SMIAPP_REG_ADDR(reg), r);
284242
285243 return r;
286244 }