1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Driver for the Texas Instruments DS90UB913 video serializer |
4 | * |
5 | * Based on a driver from Luca Ceresoli <luca@lucaceresoli.net> |
6 | * |
7 | * Copyright (c) 2019 Luca Ceresoli <luca@lucaceresoli.net> |
8 | * Copyright (c) 2023 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
9 | */ |
10 | |
11 | #include <linux/clk-provider.h> |
12 | #include <linux/clk.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/fwnode.h> |
15 | #include <linux/gpio/driver.h> |
16 | #include <linux/i2c-atr.h> |
17 | #include <linux/i2c.h> |
18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> |
20 | #include <linux/property.h> |
21 | #include <linux/regmap.h> |
22 | |
23 | #include <media/i2c/ds90ub9xx.h> |
24 | #include <media/v4l2-fwnode.h> |
25 | #include <media/v4l2-mediabus.h> |
26 | #include <media/v4l2-subdev.h> |
27 | |
28 | #define UB913_PAD_SINK 0 |
29 | #define UB913_PAD_SOURCE 1 |
30 | |
31 | /* |
32 | * UB913 has 4 gpios, but gpios 3 and 4 are reserved for external oscillator |
33 | * mode. Thus we only support 2 gpios for now. |
34 | */ |
35 | #define UB913_NUM_GPIOS 2 |
36 | |
37 | #define UB913_REG_RESET_CTL 0x01 |
38 | #define UB913_REG_RESET_CTL_DIGITAL_RESET_1 BIT(1) |
39 | #define UB913_REG_RESET_CTL_DIGITAL_RESET_0 BIT(0) |
40 | |
41 | #define UB913_REG_GENERAL_CFG 0x03 |
42 | #define UB913_REG_GENERAL_CFG_CRC_ERR_RESET BIT(5) |
43 | #define UB913_REG_GENERAL_CFG_PCLK_RISING BIT(0) |
44 | |
45 | #define UB913_REG_MODE_SEL 0x05 |
46 | #define UB913_REG_MODE_SEL_MODE_OVERRIDE BIT(5) |
47 | #define UB913_REG_MODE_SEL_MODE_UP_TO_DATE BIT(4) |
48 | #define UB913_REG_MODE_SEL_MODE_MASK GENMASK(3, 0) |
49 | |
50 | #define UB913_REG_CRC_ERRORS_LSB 0x0a |
51 | #define UB913_REG_CRC_ERRORS_MSB 0x0b |
52 | |
53 | #define UB913_REG_GENERAL_STATUS 0x0c |
54 | |
55 | #define UB913_REG_GPIO_CFG(n) (0x0d + (n)) |
56 | #define UB913_REG_GPIO_CFG_ENABLE(n) BIT(0 + (n) * 4) |
57 | #define UB913_REG_GPIO_CFG_DIR_INPUT(n) BIT(1 + (n) * 4) |
58 | #define UB913_REG_GPIO_CFG_REMOTE_EN(n) BIT(2 + (n) * 4) |
59 | #define UB913_REG_GPIO_CFG_OUT_VAL(n) BIT(3 + (n) * 4) |
60 | #define UB913_REG_GPIO_CFG_MASK(n) (0xf << ((n) * 4)) |
61 | |
62 | #define UB913_REG_SCL_HIGH_TIME 0x11 |
63 | #define UB913_REG_SCL_LOW_TIME 0x12 |
64 | |
65 | #define UB913_REG_PLL_OVR 0x35 |
66 | |
67 | struct ub913_data { |
68 | struct i2c_client *client; |
69 | struct regmap *regmap; |
70 | struct clk *clkin; |
71 | |
72 | struct gpio_chip gpio_chip; |
73 | |
74 | struct v4l2_subdev sd; |
75 | struct media_pad pads[2]; |
76 | |
77 | struct v4l2_async_notifier notifier; |
78 | |
79 | struct v4l2_subdev *source_sd; |
80 | u16 source_sd_pad; |
81 | |
82 | u64 enabled_source_streams; |
83 | |
84 | struct clk_hw *clkout_clk_hw; |
85 | |
86 | struct ds90ub9xx_platform_data *plat_data; |
87 | |
88 | bool pclk_polarity_rising; |
89 | }; |
90 | |
91 | static inline struct ub913_data *sd_to_ub913(struct v4l2_subdev *sd) |
92 | { |
93 | return container_of(sd, struct ub913_data, sd); |
94 | } |
95 | |
96 | struct ub913_format_info { |
97 | u32 incode; |
98 | u32 outcode; |
99 | }; |
100 | |
101 | static const struct ub913_format_info ub913_formats[] = { |
102 | /* Only RAW10 with 8-bit payload is supported at the moment */ |
103 | { .incode = MEDIA_BUS_FMT_YUYV8_2X8, .outcode = MEDIA_BUS_FMT_YUYV8_1X16 }, |
104 | { .incode = MEDIA_BUS_FMT_UYVY8_2X8, .outcode = MEDIA_BUS_FMT_UYVY8_1X16 }, |
105 | { .incode = MEDIA_BUS_FMT_VYUY8_2X8, .outcode = MEDIA_BUS_FMT_VYUY8_1X16 }, |
106 | { .incode = MEDIA_BUS_FMT_YVYU8_2X8, .outcode = MEDIA_BUS_FMT_YVYU8_1X16 }, |
107 | }; |
108 | |
109 | static const struct ub913_format_info *ub913_find_format(u32 incode) |
110 | { |
111 | unsigned int i; |
112 | |
113 | for (i = 0; i < ARRAY_SIZE(ub913_formats); i++) { |
114 | if (ub913_formats[i].incode == incode) |
115 | return &ub913_formats[i]; |
116 | } |
117 | |
118 | return NULL; |
119 | } |
120 | |
121 | static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val) |
122 | { |
123 | unsigned int v; |
124 | int ret; |
125 | |
126 | ret = regmap_read(map: priv->regmap, reg, val: &v); |
127 | if (ret < 0) { |
128 | dev_err(&priv->client->dev, |
129 | "Cannot read register 0x%02x: %d!\n" , reg, ret); |
130 | return ret; |
131 | } |
132 | |
133 | *val = v; |
134 | return 0; |
135 | } |
136 | |
137 | static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val) |
138 | { |
139 | int ret; |
140 | |
141 | ret = regmap_write(map: priv->regmap, reg, val); |
142 | if (ret < 0) |
143 | dev_err(&priv->client->dev, |
144 | "Cannot write register 0x%02x: %d!\n" , reg, ret); |
145 | |
146 | return ret; |
147 | } |
148 | |
149 | /* |
150 | * GPIO chip |
151 | */ |
152 | static int ub913_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) |
153 | { |
154 | return GPIO_LINE_DIRECTION_OUT; |
155 | } |
156 | |
157 | static int ub913_gpio_direction_out(struct gpio_chip *gc, unsigned int offset, |
158 | int value) |
159 | { |
160 | struct ub913_data *priv = gpiochip_get_data(gc); |
161 | unsigned int reg_idx = offset / 2; |
162 | unsigned int field_idx = offset % 2; |
163 | |
164 | return regmap_update_bits(map: priv->regmap, UB913_REG_GPIO_CFG(reg_idx), |
165 | UB913_REG_GPIO_CFG_MASK(field_idx), |
166 | UB913_REG_GPIO_CFG_ENABLE(field_idx) | |
167 | (value ? UB913_REG_GPIO_CFG_OUT_VAL(field_idx) : |
168 | 0)); |
169 | } |
170 | |
171 | static void ub913_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) |
172 | { |
173 | ub913_gpio_direction_out(gc, offset, value); |
174 | } |
175 | |
176 | static int ub913_gpio_of_xlate(struct gpio_chip *gc, |
177 | const struct of_phandle_args *gpiospec, |
178 | u32 *flags) |
179 | { |
180 | if (flags) |
181 | *flags = gpiospec->args[1]; |
182 | |
183 | return gpiospec->args[0]; |
184 | } |
185 | |
186 | static int ub913_gpiochip_probe(struct ub913_data *priv) |
187 | { |
188 | struct device *dev = &priv->client->dev; |
189 | struct gpio_chip *gc = &priv->gpio_chip; |
190 | int ret; |
191 | |
192 | /* Initialize GPIOs 0 and 1 to local control, tri-state */ |
193 | ub913_write(priv, UB913_REG_GPIO_CFG(0), val: 0); |
194 | |
195 | gc->label = dev_name(dev); |
196 | gc->parent = dev; |
197 | gc->owner = THIS_MODULE; |
198 | gc->base = -1; |
199 | gc->can_sleep = true; |
200 | gc->ngpio = UB913_NUM_GPIOS; |
201 | gc->get_direction = ub913_gpio_get_direction; |
202 | gc->direction_output = ub913_gpio_direction_out; |
203 | gc->set = ub913_gpio_set; |
204 | gc->of_xlate = ub913_gpio_of_xlate; |
205 | gc->of_gpio_n_cells = 2; |
206 | |
207 | ret = gpiochip_add_data(gc, priv); |
208 | if (ret) { |
209 | dev_err(dev, "Failed to add GPIOs: %d\n" , ret); |
210 | return ret; |
211 | } |
212 | |
213 | return 0; |
214 | } |
215 | |
216 | static void ub913_gpiochip_remove(struct ub913_data *priv) |
217 | { |
218 | gpiochip_remove(gc: &priv->gpio_chip); |
219 | } |
220 | |
221 | static const struct regmap_config ub913_regmap_config = { |
222 | .name = "ds90ub913" , |
223 | .reg_bits = 8, |
224 | .val_bits = 8, |
225 | .reg_format_endian = REGMAP_ENDIAN_DEFAULT, |
226 | .val_format_endian = REGMAP_ENDIAN_DEFAULT, |
227 | }; |
228 | |
229 | /* |
230 | * V4L2 |
231 | */ |
232 | |
233 | static int ub913_enable_streams(struct v4l2_subdev *sd, |
234 | struct v4l2_subdev_state *state, u32 pad, |
235 | u64 streams_mask) |
236 | { |
237 | struct ub913_data *priv = sd_to_ub913(sd); |
238 | u64 sink_streams; |
239 | int ret; |
240 | |
241 | sink_streams = v4l2_subdev_state_xlate_streams(state, UB913_PAD_SOURCE, |
242 | UB913_PAD_SINK, |
243 | streams: &streams_mask); |
244 | |
245 | ret = v4l2_subdev_enable_streams(sd: priv->source_sd, pad: priv->source_sd_pad, |
246 | streams_mask: sink_streams); |
247 | if (ret) |
248 | return ret; |
249 | |
250 | priv->enabled_source_streams |= streams_mask; |
251 | |
252 | return 0; |
253 | } |
254 | |
255 | static int ub913_disable_streams(struct v4l2_subdev *sd, |
256 | struct v4l2_subdev_state *state, u32 pad, |
257 | u64 streams_mask) |
258 | { |
259 | struct ub913_data *priv = sd_to_ub913(sd); |
260 | u64 sink_streams; |
261 | int ret; |
262 | |
263 | sink_streams = v4l2_subdev_state_xlate_streams(state, UB913_PAD_SOURCE, |
264 | UB913_PAD_SINK, |
265 | streams: &streams_mask); |
266 | |
267 | ret = v4l2_subdev_disable_streams(sd: priv->source_sd, pad: priv->source_sd_pad, |
268 | streams_mask: sink_streams); |
269 | if (ret) |
270 | return ret; |
271 | |
272 | priv->enabled_source_streams &= ~streams_mask; |
273 | |
274 | return 0; |
275 | } |
276 | |
277 | static int _ub913_set_routing(struct v4l2_subdev *sd, |
278 | struct v4l2_subdev_state *state, |
279 | struct v4l2_subdev_krouting *routing) |
280 | { |
281 | static const struct v4l2_mbus_framefmt in_format = { |
282 | .width = 640, |
283 | .height = 480, |
284 | .code = MEDIA_BUS_FMT_UYVY8_2X8, |
285 | .field = V4L2_FIELD_NONE, |
286 | .colorspace = V4L2_COLORSPACE_SRGB, |
287 | .ycbcr_enc = V4L2_YCBCR_ENC_601, |
288 | .quantization = V4L2_QUANTIZATION_LIM_RANGE, |
289 | .xfer_func = V4L2_XFER_FUNC_SRGB, |
290 | }; |
291 | static const struct v4l2_mbus_framefmt out_format = { |
292 | .width = 640, |
293 | .height = 480, |
294 | .code = MEDIA_BUS_FMT_UYVY8_1X16, |
295 | .field = V4L2_FIELD_NONE, |
296 | .colorspace = V4L2_COLORSPACE_SRGB, |
297 | .ycbcr_enc = V4L2_YCBCR_ENC_601, |
298 | .quantization = V4L2_QUANTIZATION_LIM_RANGE, |
299 | .xfer_func = V4L2_XFER_FUNC_SRGB, |
300 | }; |
301 | struct v4l2_subdev_stream_configs *stream_configs; |
302 | unsigned int i; |
303 | int ret; |
304 | |
305 | /* |
306 | * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until |
307 | * frame desc is made dynamically allocated. |
308 | */ |
309 | |
310 | if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX) |
311 | return -EINVAL; |
312 | |
313 | ret = v4l2_subdev_routing_validate(sd, routing, |
314 | disallow: V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); |
315 | if (ret) |
316 | return ret; |
317 | |
318 | ret = v4l2_subdev_set_routing(sd, state, routing); |
319 | if (ret) |
320 | return ret; |
321 | |
322 | stream_configs = &state->stream_configs; |
323 | |
324 | for (i = 0; i < stream_configs->num_configs; i++) { |
325 | if (stream_configs->configs[i].pad == UB913_PAD_SINK) |
326 | stream_configs->configs[i].fmt = in_format; |
327 | else |
328 | stream_configs->configs[i].fmt = out_format; |
329 | } |
330 | |
331 | return 0; |
332 | } |
333 | |
334 | static int ub913_set_routing(struct v4l2_subdev *sd, |
335 | struct v4l2_subdev_state *state, |
336 | enum v4l2_subdev_format_whence which, |
337 | struct v4l2_subdev_krouting *routing) |
338 | { |
339 | struct ub913_data *priv = sd_to_ub913(sd); |
340 | |
341 | if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams) |
342 | return -EBUSY; |
343 | |
344 | return _ub913_set_routing(sd, state, routing); |
345 | } |
346 | |
347 | static int ub913_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, |
348 | struct v4l2_mbus_frame_desc *fd) |
349 | { |
350 | struct ub913_data *priv = sd_to_ub913(sd); |
351 | const struct v4l2_subdev_krouting *routing; |
352 | struct v4l2_mbus_frame_desc source_fd; |
353 | struct v4l2_subdev_route *route; |
354 | struct v4l2_subdev_state *state; |
355 | int ret; |
356 | |
357 | if (pad != UB913_PAD_SOURCE) |
358 | return -EINVAL; |
359 | |
360 | ret = v4l2_subdev_call(priv->source_sd, pad, get_frame_desc, |
361 | priv->source_sd_pad, &source_fd); |
362 | if (ret) |
363 | return ret; |
364 | |
365 | fd->type = V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL; |
366 | |
367 | state = v4l2_subdev_lock_and_get_active_state(sd); |
368 | |
369 | routing = &state->routing; |
370 | |
371 | for_each_active_route(routing, route) { |
372 | unsigned int i; |
373 | |
374 | if (route->source_pad != pad) |
375 | continue; |
376 | |
377 | for (i = 0; i < source_fd.num_entries; i++) { |
378 | if (source_fd.entry[i].stream == route->sink_stream) |
379 | break; |
380 | } |
381 | |
382 | if (i == source_fd.num_entries) { |
383 | dev_err(&priv->client->dev, |
384 | "Failed to find stream from source frame desc\n" ); |
385 | ret = -EPIPE; |
386 | goto out_unlock; |
387 | } |
388 | |
389 | fd->entry[fd->num_entries].stream = route->source_stream; |
390 | fd->entry[fd->num_entries].flags = source_fd.entry[i].flags; |
391 | fd->entry[fd->num_entries].length = source_fd.entry[i].length; |
392 | fd->entry[fd->num_entries].pixelcode = |
393 | source_fd.entry[i].pixelcode; |
394 | |
395 | fd->num_entries++; |
396 | } |
397 | |
398 | out_unlock: |
399 | v4l2_subdev_unlock_state(state); |
400 | |
401 | return ret; |
402 | } |
403 | |
404 | static int ub913_set_fmt(struct v4l2_subdev *sd, |
405 | struct v4l2_subdev_state *state, |
406 | struct v4l2_subdev_format *format) |
407 | { |
408 | struct ub913_data *priv = sd_to_ub913(sd); |
409 | struct v4l2_mbus_framefmt *fmt; |
410 | const struct ub913_format_info *finfo; |
411 | |
412 | if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE && |
413 | priv->enabled_source_streams) |
414 | return -EBUSY; |
415 | |
416 | /* Source format is fully defined by the sink format, so not settable */ |
417 | if (format->pad == UB913_PAD_SOURCE) |
418 | return v4l2_subdev_get_fmt(sd, state, format); |
419 | |
420 | finfo = ub913_find_format(incode: format->format.code); |
421 | if (!finfo) { |
422 | finfo = &ub913_formats[0]; |
423 | format->format.code = finfo->incode; |
424 | } |
425 | |
426 | /* Set sink format */ |
427 | fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream); |
428 | if (!fmt) |
429 | return -EINVAL; |
430 | |
431 | *fmt = format->format; |
432 | |
433 | /* Propagate to source format, and adjust the mbus code */ |
434 | fmt = v4l2_subdev_state_get_opposite_stream_format(state, pad: format->pad, |
435 | stream: format->stream); |
436 | if (!fmt) |
437 | return -EINVAL; |
438 | |
439 | format->format.code = finfo->outcode; |
440 | |
441 | *fmt = format->format; |
442 | |
443 | return 0; |
444 | } |
445 | |
446 | static int ub913_init_state(struct v4l2_subdev *sd, |
447 | struct v4l2_subdev_state *state) |
448 | { |
449 | struct v4l2_subdev_route routes[] = { |
450 | { |
451 | .sink_pad = UB913_PAD_SINK, |
452 | .sink_stream = 0, |
453 | .source_pad = UB913_PAD_SOURCE, |
454 | .source_stream = 0, |
455 | .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, |
456 | }, |
457 | }; |
458 | |
459 | struct v4l2_subdev_krouting routing = { |
460 | .num_routes = ARRAY_SIZE(routes), |
461 | .routes = routes, |
462 | }; |
463 | |
464 | return _ub913_set_routing(sd, state, routing: &routing); |
465 | } |
466 | |
467 | static int ub913_log_status(struct v4l2_subdev *sd) |
468 | { |
469 | struct ub913_data *priv = sd_to_ub913(sd); |
470 | struct device *dev = &priv->client->dev; |
471 | u8 v = 0, v1 = 0, v2 = 0; |
472 | |
473 | ub913_read(priv, UB913_REG_MODE_SEL, val: &v); |
474 | dev_info(dev, "MODE_SEL %#02x\n" , v); |
475 | |
476 | ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, val: &v1); |
477 | ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, val: &v2); |
478 | dev_info(dev, "CRC errors %u\n" , v1 | (v2 << 8)); |
479 | |
480 | /* clear CRC errors */ |
481 | ub913_read(priv, UB913_REG_GENERAL_CFG, val: &v); |
482 | ub913_write(priv, UB913_REG_GENERAL_CFG, |
483 | val: v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET); |
484 | ub913_write(priv, UB913_REG_GENERAL_CFG, val: v); |
485 | |
486 | ub913_read(priv, UB913_REG_GENERAL_STATUS, val: &v); |
487 | dev_info(dev, "GENERAL_STATUS %#02x\n" , v); |
488 | |
489 | ub913_read(priv, UB913_REG_PLL_OVR, val: &v); |
490 | dev_info(dev, "PLL_OVR %#02x\n" , v); |
491 | |
492 | return 0; |
493 | } |
494 | |
495 | static const struct v4l2_subdev_core_ops ub913_subdev_core_ops = { |
496 | .log_status = ub913_log_status, |
497 | }; |
498 | |
499 | static const struct v4l2_subdev_pad_ops ub913_pad_ops = { |
500 | .enable_streams = ub913_enable_streams, |
501 | .disable_streams = ub913_disable_streams, |
502 | .set_routing = ub913_set_routing, |
503 | .get_frame_desc = ub913_get_frame_desc, |
504 | .get_fmt = v4l2_subdev_get_fmt, |
505 | .set_fmt = ub913_set_fmt, |
506 | }; |
507 | |
508 | static const struct v4l2_subdev_ops ub913_subdev_ops = { |
509 | .core = &ub913_subdev_core_ops, |
510 | .pad = &ub913_pad_ops, |
511 | }; |
512 | |
513 | static const struct v4l2_subdev_internal_ops ub913_internal_ops = { |
514 | .init_state = ub913_init_state, |
515 | }; |
516 | |
517 | static const struct media_entity_operations ub913_entity_ops = { |
518 | .link_validate = v4l2_subdev_link_validate, |
519 | }; |
520 | |
521 | static int ub913_notify_bound(struct v4l2_async_notifier *notifier, |
522 | struct v4l2_subdev *source_subdev, |
523 | struct v4l2_async_connection *asd) |
524 | { |
525 | struct ub913_data *priv = sd_to_ub913(sd: notifier->sd); |
526 | struct device *dev = &priv->client->dev; |
527 | int ret; |
528 | |
529 | ret = media_entity_get_fwnode_pad(entity: &source_subdev->entity, |
530 | fwnode: source_subdev->fwnode, |
531 | MEDIA_PAD_FL_SOURCE); |
532 | if (ret < 0) { |
533 | dev_err(dev, "Failed to find pad for %s\n" , |
534 | source_subdev->name); |
535 | return ret; |
536 | } |
537 | |
538 | priv->source_sd = source_subdev; |
539 | priv->source_sd_pad = ret; |
540 | |
541 | ret = media_create_pad_link(source: &source_subdev->entity, source_pad: priv->source_sd_pad, |
542 | sink: &priv->sd.entity, UB913_PAD_SINK, |
543 | MEDIA_LNK_FL_ENABLED | |
544 | MEDIA_LNK_FL_IMMUTABLE); |
545 | if (ret) { |
546 | dev_err(dev, "Unable to link %s:%u -> %s:0\n" , |
547 | source_subdev->name, priv->source_sd_pad, |
548 | priv->sd.name); |
549 | return ret; |
550 | } |
551 | |
552 | return 0; |
553 | } |
554 | |
555 | static const struct v4l2_async_notifier_operations ub913_notify_ops = { |
556 | .bound = ub913_notify_bound, |
557 | }; |
558 | |
559 | static int ub913_v4l2_notifier_register(struct ub913_data *priv) |
560 | { |
561 | struct device *dev = &priv->client->dev; |
562 | struct v4l2_async_connection *asd; |
563 | struct fwnode_handle *ep_fwnode; |
564 | int ret; |
565 | |
566 | ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), |
567 | UB913_PAD_SINK, endpoint: 0, flags: 0); |
568 | if (!ep_fwnode) { |
569 | dev_err(dev, "No graph endpoint\n" ); |
570 | return -ENODEV; |
571 | } |
572 | |
573 | v4l2_async_subdev_nf_init(notifier: &priv->notifier, sd: &priv->sd); |
574 | |
575 | asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode, |
576 | struct v4l2_async_connection); |
577 | |
578 | fwnode_handle_put(fwnode: ep_fwnode); |
579 | |
580 | if (IS_ERR(ptr: asd)) { |
581 | dev_err(dev, "Failed to add subdev: %ld" , PTR_ERR(asd)); |
582 | v4l2_async_nf_cleanup(notifier: &priv->notifier); |
583 | return PTR_ERR(ptr: asd); |
584 | } |
585 | |
586 | priv->notifier.ops = &ub913_notify_ops; |
587 | |
588 | ret = v4l2_async_nf_register(notifier: &priv->notifier); |
589 | if (ret) { |
590 | dev_err(dev, "Failed to register subdev_notifier" ); |
591 | v4l2_async_nf_cleanup(notifier: &priv->notifier); |
592 | return ret; |
593 | } |
594 | |
595 | return 0; |
596 | } |
597 | |
598 | static void ub913_v4l2_nf_unregister(struct ub913_data *priv) |
599 | { |
600 | v4l2_async_nf_unregister(notifier: &priv->notifier); |
601 | v4l2_async_nf_cleanup(notifier: &priv->notifier); |
602 | } |
603 | |
604 | static int ub913_register_clkout(struct ub913_data *priv) |
605 | { |
606 | struct device *dev = &priv->client->dev; |
607 | const char *name; |
608 | int ret; |
609 | |
610 | name = kasprintf(GFP_KERNEL, fmt: "ds90ub913.%s.clk_out" , dev_name(dev)); |
611 | if (!name) |
612 | return -ENOMEM; |
613 | |
614 | priv->clkout_clk_hw = devm_clk_hw_register_fixed_factor(dev, name, |
615 | parent_name: __clk_get_name(clk: priv->clkin), flags: 0, mult: 1, div: 2); |
616 | |
617 | kfree(objp: name); |
618 | |
619 | if (IS_ERR(ptr: priv->clkout_clk_hw)) |
620 | return dev_err_probe(dev, err: PTR_ERR(ptr: priv->clkout_clk_hw), |
621 | fmt: "Cannot register clkout hw\n" ); |
622 | |
623 | ret = devm_of_clk_add_hw_provider(dev, get: of_clk_hw_simple_get, |
624 | data: priv->clkout_clk_hw); |
625 | if (ret) |
626 | return dev_err_probe(dev, err: ret, |
627 | fmt: "Cannot add OF clock provider\n" ); |
628 | |
629 | return 0; |
630 | } |
631 | |
632 | static int ub913_i2c_master_init(struct ub913_data *priv) |
633 | { |
634 | /* i2c fast mode */ |
635 | u32 scl_high = 600 + 300; /* high period + rise time, ns */ |
636 | u32 scl_low = 1300 + 300; /* low period + fall time, ns */ |
637 | unsigned long ref; |
638 | int ret; |
639 | |
640 | ref = clk_get_rate(clk: priv->clkin) / 2; |
641 | |
642 | scl_high = div64_u64(dividend: (u64)scl_high * ref, divisor: 1000000000); |
643 | scl_low = div64_u64(dividend: (u64)scl_low * ref, divisor: 1000000000); |
644 | |
645 | ret = ub913_write(priv, UB913_REG_SCL_HIGH_TIME, val: scl_high); |
646 | if (ret) |
647 | return ret; |
648 | |
649 | ret = ub913_write(priv, UB913_REG_SCL_LOW_TIME, val: scl_low); |
650 | if (ret) |
651 | return ret; |
652 | |
653 | return 0; |
654 | } |
655 | |
656 | static int ub913_add_i2c_adapter(struct ub913_data *priv) |
657 | { |
658 | struct device *dev = &priv->client->dev; |
659 | struct fwnode_handle *i2c_handle; |
660 | int ret; |
661 | |
662 | i2c_handle = device_get_named_child_node(dev, childname: "i2c" ); |
663 | if (!i2c_handle) |
664 | return 0; |
665 | |
666 | ret = i2c_atr_add_adapter(atr: priv->plat_data->atr, chan_id: priv->plat_data->port, |
667 | adapter_parent: dev, bus_handle: i2c_handle); |
668 | |
669 | fwnode_handle_put(fwnode: i2c_handle); |
670 | |
671 | if (ret) |
672 | return ret; |
673 | |
674 | return 0; |
675 | } |
676 | |
677 | static int ub913_parse_dt(struct ub913_data *priv) |
678 | { |
679 | struct device *dev = &priv->client->dev; |
680 | struct v4l2_fwnode_endpoint vep = { |
681 | .bus_type = V4L2_MBUS_PARALLEL, |
682 | }; |
683 | struct fwnode_handle *ep_fwnode; |
684 | int ret; |
685 | |
686 | ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), |
687 | UB913_PAD_SINK, endpoint: 0, flags: 0); |
688 | if (!ep_fwnode) |
689 | return dev_err_probe(dev, err: -ENOENT, fmt: "No sink endpoint\n" ); |
690 | |
691 | ret = v4l2_fwnode_endpoint_parse(fwnode: ep_fwnode, vep: &vep); |
692 | |
693 | fwnode_handle_put(fwnode: ep_fwnode); |
694 | |
695 | if (ret) |
696 | return dev_err_probe(dev, err: ret, |
697 | fmt: "failed to parse sink endpoint data\n" ); |
698 | |
699 | if (vep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_RISING) |
700 | priv->pclk_polarity_rising = true; |
701 | else if (vep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) |
702 | priv->pclk_polarity_rising = false; |
703 | else |
704 | return dev_err_probe(dev, err: -EINVAL, |
705 | fmt: "bad value for 'pclk-sample'\n" ); |
706 | |
707 | return 0; |
708 | } |
709 | |
710 | static int ub913_hw_init(struct ub913_data *priv) |
711 | { |
712 | struct device *dev = &priv->client->dev; |
713 | bool mode_override; |
714 | u8 mode; |
715 | int ret; |
716 | u8 v; |
717 | |
718 | ret = ub913_read(priv, UB913_REG_MODE_SEL, val: &v); |
719 | if (ret) |
720 | return ret; |
721 | |
722 | if (!(v & UB913_REG_MODE_SEL_MODE_UP_TO_DATE)) |
723 | return dev_err_probe(dev, err: -ENODEV, |
724 | fmt: "Mode value not stabilized\n" ); |
725 | |
726 | mode_override = v & UB913_REG_MODE_SEL_MODE_OVERRIDE; |
727 | mode = v & UB913_REG_MODE_SEL_MODE_MASK; |
728 | |
729 | dev_dbg(dev, "mode from %s: %#x\n" , |
730 | mode_override ? "reg" : "deserializer" , mode); |
731 | |
732 | ret = ub913_i2c_master_init(priv); |
733 | if (ret) |
734 | return dev_err_probe(dev, err: ret, fmt: "i2c master init failed\n" ); |
735 | |
736 | ub913_read(priv, UB913_REG_GENERAL_CFG, val: &v); |
737 | v &= ~UB913_REG_GENERAL_CFG_PCLK_RISING; |
738 | v |= priv->pclk_polarity_rising ? UB913_REG_GENERAL_CFG_PCLK_RISING : 0; |
739 | ub913_write(priv, UB913_REG_GENERAL_CFG, val: v); |
740 | |
741 | return 0; |
742 | } |
743 | |
744 | static int ub913_subdev_init(struct ub913_data *priv) |
745 | { |
746 | struct device *dev = &priv->client->dev; |
747 | int ret; |
748 | |
749 | v4l2_i2c_subdev_init(sd: &priv->sd, client: priv->client, ops: &ub913_subdev_ops); |
750 | priv->sd.internal_ops = &ub913_internal_ops; |
751 | priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; |
752 | priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; |
753 | priv->sd.entity.ops = &ub913_entity_ops; |
754 | |
755 | priv->pads[0].flags = MEDIA_PAD_FL_SINK; |
756 | priv->pads[1].flags = MEDIA_PAD_FL_SOURCE; |
757 | |
758 | ret = media_entity_pads_init(entity: &priv->sd.entity, num_pads: 2, pads: priv->pads); |
759 | if (ret) |
760 | return dev_err_probe(dev, err: ret, fmt: "Failed to init pads\n" ); |
761 | |
762 | ret = v4l2_subdev_init_finalize(&priv->sd); |
763 | if (ret) |
764 | goto err_entity_cleanup; |
765 | |
766 | ret = ub913_v4l2_notifier_register(priv); |
767 | if (ret) { |
768 | dev_err_probe(dev, err: ret, |
769 | fmt: "v4l2 subdev notifier register failed\n" ); |
770 | goto err_subdev_cleanup; |
771 | } |
772 | |
773 | ret = v4l2_async_register_subdev(sd: &priv->sd); |
774 | if (ret) { |
775 | dev_err_probe(dev, err: ret, fmt: "v4l2_async_register_subdev error\n" ); |
776 | goto err_unreg_notif; |
777 | } |
778 | |
779 | return 0; |
780 | |
781 | err_unreg_notif: |
782 | ub913_v4l2_nf_unregister(priv); |
783 | err_subdev_cleanup: |
784 | v4l2_subdev_cleanup(sd: &priv->sd); |
785 | err_entity_cleanup: |
786 | media_entity_cleanup(entity: &priv->sd.entity); |
787 | |
788 | return ret; |
789 | } |
790 | |
791 | static void ub913_subdev_uninit(struct ub913_data *priv) |
792 | { |
793 | v4l2_async_unregister_subdev(sd: &priv->sd); |
794 | ub913_v4l2_nf_unregister(priv); |
795 | v4l2_subdev_cleanup(sd: &priv->sd); |
796 | fwnode_handle_put(fwnode: priv->sd.fwnode); |
797 | media_entity_cleanup(entity: &priv->sd.entity); |
798 | } |
799 | |
800 | static int ub913_probe(struct i2c_client *client) |
801 | { |
802 | struct device *dev = &client->dev; |
803 | struct ub913_data *priv; |
804 | int ret; |
805 | |
806 | priv = devm_kzalloc(dev, size: sizeof(*priv), GFP_KERNEL); |
807 | if (!priv) |
808 | return -ENOMEM; |
809 | |
810 | priv->client = client; |
811 | |
812 | priv->plat_data = dev_get_platdata(dev: &client->dev); |
813 | if (!priv->plat_data) |
814 | return dev_err_probe(dev, err: -ENODEV, fmt: "Platform data missing\n" ); |
815 | |
816 | priv->regmap = devm_regmap_init_i2c(client, &ub913_regmap_config); |
817 | if (IS_ERR(ptr: priv->regmap)) |
818 | return dev_err_probe(dev, err: PTR_ERR(ptr: priv->regmap), |
819 | fmt: "Failed to init regmap\n" ); |
820 | |
821 | /* |
822 | * ub913 can also work without ext clock, but that is not supported by |
823 | * the driver yet. |
824 | */ |
825 | priv->clkin = devm_clk_get(dev, id: "clkin" ); |
826 | if (IS_ERR(ptr: priv->clkin)) |
827 | return dev_err_probe(dev, err: PTR_ERR(ptr: priv->clkin), |
828 | fmt: "Cannot get CLKIN\n" ); |
829 | |
830 | ret = ub913_parse_dt(priv); |
831 | if (ret) |
832 | return ret; |
833 | |
834 | ret = ub913_hw_init(priv); |
835 | if (ret) |
836 | return ret; |
837 | |
838 | ret = ub913_gpiochip_probe(priv); |
839 | if (ret) |
840 | return dev_err_probe(dev, err: ret, fmt: "Failed to init gpiochip\n" ); |
841 | |
842 | ret = ub913_register_clkout(priv); |
843 | if (ret) { |
844 | dev_err_probe(dev, err: ret, fmt: "Failed to register clkout\n" ); |
845 | goto err_gpiochip_remove; |
846 | } |
847 | |
848 | ret = ub913_subdev_init(priv); |
849 | if (ret) |
850 | goto err_gpiochip_remove; |
851 | |
852 | ret = ub913_add_i2c_adapter(priv); |
853 | if (ret) { |
854 | dev_err_probe(dev, err: ret, fmt: "failed to add remote i2c adapter\n" ); |
855 | goto err_subdev_uninit; |
856 | } |
857 | |
858 | return 0; |
859 | |
860 | err_subdev_uninit: |
861 | ub913_subdev_uninit(priv); |
862 | err_gpiochip_remove: |
863 | ub913_gpiochip_remove(priv); |
864 | |
865 | return ret; |
866 | } |
867 | |
868 | static void ub913_remove(struct i2c_client *client) |
869 | { |
870 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
871 | struct ub913_data *priv = sd_to_ub913(sd); |
872 | |
873 | i2c_atr_del_adapter(atr: priv->plat_data->atr, chan_id: priv->plat_data->port); |
874 | |
875 | ub913_subdev_uninit(priv); |
876 | |
877 | ub913_gpiochip_remove(priv); |
878 | } |
879 | |
880 | static const struct i2c_device_id ub913_id[] = { { "ds90ub913a-q1" , 0 }, {} }; |
881 | MODULE_DEVICE_TABLE(i2c, ub913_id); |
882 | |
883 | static const struct of_device_id ub913_dt_ids[] = { |
884 | { .compatible = "ti,ds90ub913a-q1" }, |
885 | {} |
886 | }; |
887 | MODULE_DEVICE_TABLE(of, ub913_dt_ids); |
888 | |
889 | static struct i2c_driver ds90ub913_driver = { |
890 | .probe = ub913_probe, |
891 | .remove = ub913_remove, |
892 | .id_table = ub913_id, |
893 | .driver = { |
894 | .name = "ds90ub913a" , |
895 | .of_match_table = ub913_dt_ids, |
896 | }, |
897 | }; |
898 | module_i2c_driver(ds90ub913_driver); |
899 | |
900 | MODULE_LICENSE("GPL" ); |
901 | MODULE_DESCRIPTION("Texas Instruments DS90UB913 FPD-Link III Serializer Driver" ); |
902 | MODULE_AUTHOR("Luca Ceresoli <luca@lucaceresoli.net>" ); |
903 | MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>" ); |
904 | MODULE_IMPORT_NS(I2C_ATR); |
905 | |