1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Maxim MAX9286 Quad GMSL2 Deserializer Driver
4 *
5 * Copyright (C) 2021 Renesas Electronics Corporation
6 * Copyright (C) 2021 Niklas Söderlund
7 */
8
9 #include <linux/delay.h>
10 #include <linux/i2c.h>
11 #include <linux/module.h>
12 #include <linux/of_graph.h>
13 #include <linux/regmap.h>
14
15 #include <media/v4l2-ctrls.h>
16 #include <media/v4l2-fwnode.h>
17 #include <media/v4l2-subdev.h>
18
19 #define MAX96712_ID 0x20
20
21 #define MAX96712_DPLL_FREQ 1000
22
23 enum max96712_pattern {
24 MAX96712_PATTERN_CHECKERBOARD = 0,
25 MAX96712_PATTERN_GRADIENT,
26 };
27
28 struct max96712_priv {
29 struct i2c_client *client;
30 struct regmap *regmap;
31 struct gpio_desc *gpiod_pwdn;
32
33 struct v4l2_mbus_config_mipi_csi2 mipi;
34
35 struct v4l2_subdev sd;
36 struct v4l2_ctrl_handler ctrl_handler;
37 struct media_pad pads[1];
38
39 enum max96712_pattern pattern;
40 };
41
max96712_read(struct max96712_priv * priv,int reg)42 static int max96712_read(struct max96712_priv *priv, int reg)
43 {
44 int ret, val;
45
46 ret = regmap_read(priv->regmap, reg, &val);
47 if (ret) {
48 dev_err(&priv->client->dev, "read 0x%04x failed\n", reg);
49 return ret;
50 }
51
52 return val;
53 }
54
max96712_write(struct max96712_priv * priv,unsigned int reg,u8 val)55 static int max96712_write(struct max96712_priv *priv, unsigned int reg, u8 val)
56 {
57 int ret;
58
59 ret = regmap_write(priv->regmap, reg, val);
60 if (ret)
61 dev_err(&priv->client->dev, "write 0x%04x failed\n", reg);
62
63 return ret;
64 }
65
max96712_update_bits(struct max96712_priv * priv,unsigned int reg,u8 mask,u8 val)66 static int max96712_update_bits(struct max96712_priv *priv, unsigned int reg,
67 u8 mask, u8 val)
68 {
69 int ret;
70
71 ret = regmap_update_bits(priv->regmap, reg, mask, val);
72 if (ret)
73 dev_err(&priv->client->dev, "update 0x%04x failed\n", reg);
74
75 return ret;
76 }
77
max96712_write_bulk(struct max96712_priv * priv,unsigned int reg,const void * val,size_t val_count)78 static int max96712_write_bulk(struct max96712_priv *priv, unsigned int reg,
79 const void *val, size_t val_count)
80 {
81 int ret;
82
83 ret = regmap_bulk_write(priv->regmap, reg, val, val_count);
84 if (ret)
85 dev_err(&priv->client->dev, "bulk write 0x%04x failed\n", reg);
86
87 return ret;
88 }
89
max96712_write_bulk_value(struct max96712_priv * priv,unsigned int reg,unsigned int val,size_t val_count)90 static int max96712_write_bulk_value(struct max96712_priv *priv,
91 unsigned int reg, unsigned int val,
92 size_t val_count)
93 {
94 unsigned int i;
95 u8 values[4];
96
97 for (i = 1; i <= val_count; i++)
98 values[i - 1] = (val >> ((val_count - i) * 8)) & 0xff;
99
100 return max96712_write_bulk(priv, reg, &values, val_count);
101 }
102
max96712_reset(struct max96712_priv * priv)103 static void max96712_reset(struct max96712_priv *priv)
104 {
105 max96712_update_bits(priv, 0x13, 0x40, 0x40);
106 msleep(20);
107 }
108
max96712_mipi_enable(struct max96712_priv * priv,bool enable)109 static void max96712_mipi_enable(struct max96712_priv *priv, bool enable)
110 {
111 if (enable) {
112 max96712_update_bits(priv, 0x40b, 0x02, 0x02);
113 max96712_update_bits(priv, 0x8a0, 0x80, 0x80);
114 } else {
115 max96712_update_bits(priv, 0x8a0, 0x80, 0x00);
116 max96712_update_bits(priv, 0x40b, 0x02, 0x00);
117 }
118 }
119
max96712_mipi_configure(struct max96712_priv * priv)120 static void max96712_mipi_configure(struct max96712_priv *priv)
121 {
122 unsigned int i;
123 u8 phy5 = 0;
124
125 max96712_mipi_enable(priv, false);
126
127 /* Select 2x4 mode. */
128 max96712_write(priv, 0x8a0, 0x04);
129
130 /* Configure a 4-lane DPHY using PHY0 and PHY1. */
131 /* TODO: Add support for 2-lane and 1-lane configurations. */
132 /* TODO: Add support CPHY mode. */
133 max96712_write(priv, 0x94a, 0xc0);
134
135 /* Configure lane mapping for PHY0 and PHY1. */
136 /* TODO: Add support for lane swapping. */
137 max96712_write(priv, 0x8a3, 0xe4);
138
139 /* Configure lane polarity for PHY0 and PHY1. */
140 for (i = 0; i < priv->mipi.num_data_lanes + 1; i++)
141 if (priv->mipi.lane_polarities[i])
142 phy5 |= BIT(i == 0 ? 5 : i < 3 ? i - 1 : i);
143 max96712_write(priv, 0x8a5, phy5);
144
145 /* Set link frequency for PHY0 and PHY1. */
146 max96712_update_bits(priv, 0x415, 0x3f,
147 ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));
148 max96712_update_bits(priv, 0x418, 0x3f,
149 ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));
150
151 /* Enable PHY0 and PHY1 */
152 max96712_update_bits(priv, 0x8a2, 0xf0, 0x30);
153 }
154
max96712_pattern_enable(struct max96712_priv * priv,bool enable)155 static void max96712_pattern_enable(struct max96712_priv *priv, bool enable)
156 {
157 const u32 h_active = 1920;
158 const u32 h_fp = 88;
159 const u32 h_sw = 44;
160 const u32 h_bp = 148;
161 const u32 h_tot = h_active + h_fp + h_sw + h_bp;
162
163 const u32 v_active = 1080;
164 const u32 v_fp = 4;
165 const u32 v_sw = 5;
166 const u32 v_bp = 36;
167 const u32 v_tot = v_active + v_fp + v_sw + v_bp;
168
169 if (!enable) {
170 max96712_write(priv, 0x1051, 0x00);
171 return;
172 }
173
174 /* PCLK 75MHz. */
175 max96712_write(priv, 0x0009, 0x01);
176
177 /* Configure Video Timing Generator for 1920x1080 @ 30 fps. */
178 max96712_write_bulk_value(priv, 0x1052, 0, 3);
179 max96712_write_bulk_value(priv, 0x1055, v_sw * h_tot, 3);
180 max96712_write_bulk_value(priv, 0x1058,
181 (v_active + v_fp + + v_bp) * h_tot, 3);
182 max96712_write_bulk_value(priv, 0x105b, 0, 3);
183 max96712_write_bulk_value(priv, 0x105e, h_sw, 2);
184 max96712_write_bulk_value(priv, 0x1060, h_active + h_fp + h_bp, 2);
185 max96712_write_bulk_value(priv, 0x1062, v_tot, 2);
186 max96712_write_bulk_value(priv, 0x1064,
187 h_tot * (v_sw + v_bp) + (h_sw + h_bp), 3);
188 max96712_write_bulk_value(priv, 0x1067, h_active, 2);
189 max96712_write_bulk_value(priv, 0x1069, h_fp + h_sw + h_bp, 2);
190 max96712_write_bulk_value(priv, 0x106b, v_active, 2);
191
192 /* Generate VS, HS and DE in free-running mode. */
193 max96712_write(priv, 0x1050, 0xfb);
194
195 /* Configure Video Pattern Generator. */
196 if (priv->pattern == MAX96712_PATTERN_CHECKERBOARD) {
197 /* Set checkerboard pattern size. */
198 max96712_write(priv, 0x1074, 0x3c);
199 max96712_write(priv, 0x1075, 0x3c);
200 max96712_write(priv, 0x1076, 0x3c);
201
202 /* Set checkerboard pattern colors. */
203 max96712_write_bulk_value(priv, 0x106e, 0xfecc00, 3);
204 max96712_write_bulk_value(priv, 0x1071, 0x006aa7, 3);
205
206 /* Generate checkerboard pattern. */
207 max96712_write(priv, 0x1051, 0x10);
208 } else {
209 /* Set gradient increment. */
210 max96712_write(priv, 0x106d, 0x10);
211
212 /* Generate gradient pattern. */
213 max96712_write(priv, 0x1051, 0x20);
214 }
215 }
216
max96712_s_stream(struct v4l2_subdev * sd,int enable)217 static int max96712_s_stream(struct v4l2_subdev *sd, int enable)
218 {
219 struct max96712_priv *priv = v4l2_get_subdevdata(sd);
220
221 if (enable) {
222 max96712_pattern_enable(priv, true);
223 max96712_mipi_enable(priv, true);
224 } else {
225 max96712_mipi_enable(priv, false);
226 max96712_pattern_enable(priv, false);
227 }
228
229 return 0;
230 }
231
232 static const struct v4l2_subdev_video_ops max96712_video_ops = {
233 .s_stream = max96712_s_stream,
234 };
235
max96712_get_pad_format(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * format)236 static int max96712_get_pad_format(struct v4l2_subdev *sd,
237 struct v4l2_subdev_state *sd_state,
238 struct v4l2_subdev_format *format)
239 {
240 format->format.width = 1920;
241 format->format.height = 1080;
242 format->format.code = MEDIA_BUS_FMT_RGB888_1X24;
243 format->format.field = V4L2_FIELD_NONE;
244
245 return 0;
246 }
247
248 static const struct v4l2_subdev_pad_ops max96712_pad_ops = {
249 .get_fmt = max96712_get_pad_format,
250 .set_fmt = max96712_get_pad_format,
251 };
252
253 static const struct v4l2_subdev_ops max96712_subdev_ops = {
254 .video = &max96712_video_ops,
255 .pad = &max96712_pad_ops,
256 };
257
258 static const char * const max96712_test_pattern[] = {
259 "Checkerboard",
260 "Gradient",
261 };
262
max96712_s_ctrl(struct v4l2_ctrl * ctrl)263 static int max96712_s_ctrl(struct v4l2_ctrl *ctrl)
264 {
265 struct max96712_priv *priv =
266 container_of(ctrl->handler, struct max96712_priv, ctrl_handler);
267
268 switch (ctrl->id) {
269 case V4L2_CID_TEST_PATTERN:
270 priv->pattern = ctrl->val ?
271 MAX96712_PATTERN_GRADIENT :
272 MAX96712_PATTERN_CHECKERBOARD;
273 break;
274 }
275 return 0;
276 }
277
278 static const struct v4l2_ctrl_ops max96712_ctrl_ops = {
279 .s_ctrl = max96712_s_ctrl,
280 };
281
max96712_v4l2_register(struct max96712_priv * priv)282 static int max96712_v4l2_register(struct max96712_priv *priv)
283 {
284 long pixel_rate;
285 int ret;
286
287 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96712_subdev_ops);
288 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
289 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
290
291 v4l2_ctrl_handler_init(&priv->ctrl_handler, 2);
292
293 /*
294 * TODO: Once V4L2_CID_LINK_FREQ is changed from a menu control to an
295 * INT64 control it should be used here instead of V4L2_CID_PIXEL_RATE.
296 */
297 pixel_rate = MAX96712_DPLL_FREQ / priv->mipi.num_data_lanes * 1000000;
298 v4l2_ctrl_new_std(&priv->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
299 pixel_rate, pixel_rate, 1, pixel_rate);
300
301 v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &max96712_ctrl_ops,
302 V4L2_CID_TEST_PATTERN,
303 ARRAY_SIZE(max96712_test_pattern) - 1,
304 0, 0, max96712_test_pattern);
305
306 priv->sd.ctrl_handler = &priv->ctrl_handler;
307 ret = priv->ctrl_handler.error;
308 if (ret)
309 goto error;
310
311 priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
312 ret = media_entity_pads_init(&priv->sd.entity, 1, priv->pads);
313 if (ret)
314 goto error;
315
316 v4l2_set_subdevdata(&priv->sd, priv);
317
318 ret = v4l2_async_register_subdev(&priv->sd);
319 if (ret < 0) {
320 dev_err(&priv->client->dev, "Unable to register subdevice\n");
321 goto error;
322 }
323
324 return 0;
325 error:
326 v4l2_ctrl_handler_free(&priv->ctrl_handler);
327
328 return ret;
329 }
330
max96712_parse_dt(struct max96712_priv * priv)331 static int max96712_parse_dt(struct max96712_priv *priv)
332 {
333 struct fwnode_handle *ep;
334 struct v4l2_fwnode_endpoint v4l2_ep = {
335 .bus_type = V4L2_MBUS_CSI2_DPHY
336 };
337 int ret;
338
339 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(&priv->client->dev), 4,
340 0, 0);
341 if (!ep) {
342 dev_err(&priv->client->dev, "Not connected to subdevice\n");
343 return -EINVAL;
344 }
345
346 ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
347 fwnode_handle_put(ep);
348 if (ret) {
349 dev_err(&priv->client->dev, "Could not parse v4l2 endpoint\n");
350 return -EINVAL;
351 }
352
353 if (v4l2_ep.bus.mipi_csi2.num_data_lanes != 4) {
354 dev_err(&priv->client->dev, "Only 4 data lanes supported\n");
355 return -EINVAL;
356 }
357
358 priv->mipi = v4l2_ep.bus.mipi_csi2;
359
360 return 0;
361 }
362
363 static const struct regmap_config max96712_i2c_regmap = {
364 .reg_bits = 16,
365 .val_bits = 8,
366 .max_register = 0x1f00,
367 };
368
max96712_probe(struct i2c_client * client)369 static int max96712_probe(struct i2c_client *client)
370 {
371 struct max96712_priv *priv;
372 int ret;
373
374 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
375 if (!priv)
376 return -ENOMEM;
377
378 priv->client = client;
379 i2c_set_clientdata(client, priv);
380
381 priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap);
382 if (IS_ERR(priv->regmap))
383 return PTR_ERR(priv->regmap);
384
385 priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
386 GPIOD_OUT_HIGH);
387 if (IS_ERR(priv->gpiod_pwdn))
388 return PTR_ERR(priv->gpiod_pwdn);
389
390 gpiod_set_consumer_name(priv->gpiod_pwdn, "max96712-pwdn");
391 gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
392
393 if (priv->gpiod_pwdn)
394 usleep_range(4000, 5000);
395
396 if (max96712_read(priv, 0x4a) != MAX96712_ID)
397 return -ENODEV;
398
399 max96712_reset(priv);
400
401 ret = max96712_parse_dt(priv);
402 if (ret)
403 return ret;
404
405 max96712_mipi_configure(priv);
406
407 return max96712_v4l2_register(priv);
408 }
409
max96712_remove(struct i2c_client * client)410 static void max96712_remove(struct i2c_client *client)
411 {
412 struct max96712_priv *priv = i2c_get_clientdata(client);
413
414 v4l2_async_unregister_subdev(&priv->sd);
415
416 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
417 }
418
419 static const struct of_device_id max96712_of_table[] = {
420 { .compatible = "maxim,max96712" },
421 { /* sentinel */ },
422 };
423 MODULE_DEVICE_TABLE(of, max96712_of_table);
424
425 static struct i2c_driver max96712_i2c_driver = {
426 .driver = {
427 .name = "max96712",
428 .of_match_table = of_match_ptr(max96712_of_table),
429 },
430 .probe_new = max96712_probe,
431 .remove = max96712_remove,
432 };
433
434 module_i2c_driver(max96712_i2c_driver);
435
436 MODULE_DESCRIPTION("Maxim MAX96712 Quad GMSL2 Deserializer Driver");
437 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
438 MODULE_LICENSE("GPL");
439