aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSathishkumar S2014-02-25 01:12:56 -0600
committerArthur Philpott2014-03-11 18:24:49 -0500
commitbfcfdedba5ae7fda55ac631571a45a5ed877f3e8 (patch)
tree835efdfab5e67f4cf7183701ce5b4168bfb9269b
parent50ddb384a2672c25e5c219509b7bc9da25cbcf1e (diff)
downloadkernel-video-bfcfdedba5ae7fda55ac631571a45a5ed877f3e8.tar.gz
kernel-video-bfcfdedba5ae7fda55ac631571a45a5ed877f3e8.tar.xz
kernel-video-bfcfdedba5ae7fda55ac631571a45a5ed877f3e8.zip
i2c: tvp5158: Analog camera Driver Support
Add support for TVP5158 video decoder. This driver does the default initialization for single channel NTSC decode. It is tested with NTSC camera source. Change-Id: Ida5a9b45414a917bd6f515882fe72a4b4b8e0947 Signed-off-by: Sathishkumar S <sathish.omap@gmail.com>
-rw-r--r--drivers/media/i2c/Kconfig11
-rw-r--r--drivers/media/i2c/Makefile1
-rw-r--r--drivers/media/i2c/tvp5158.c672
3 files changed, 684 insertions, 0 deletions
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index c9ea9eb1ff4..ff9845c8eff 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -433,6 +433,17 @@ config VIDEO_OV1063X
433 This is a Video4Linux2 sensor-level driver for the OmniVision 433 This is a Video4Linux2 sensor-level driver for the OmniVision
434 OV1063X Sensor. 434 OV1063X Sensor.
435 435
436config VIDEO_TVP5158
437 tristate "Analog video decoder TVP5158 support NTSC/PAL"
438 depends on I2C && VIDEO_V4L2
439 depends on MEDIA_CAMERA_SUPPORT
440 ---help---
441 This is a Video4Linux2 sensor-level driver for the TVP5158
442 NTSC/PAL video decoder.
443
444 To compile this driver as a module, choose M here: the
445 module will be called tvp5158.
446
436config VIDEO_VS6624 447config VIDEO_VS6624
437 tristate "ST VS6624 sensor support" 448 tristate "ST VS6624 sensor support"
438 depends on VIDEO_V4L2 && I2C 449 depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index c081c244db4..90d46063124 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
48obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o 48obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
49obj-$(CONFIG_VIDEO_OV7670) += ov7670.o 49obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
50obj-$(CONFIG_VIDEO_OV1063X) += ov1063x.o 50obj-$(CONFIG_VIDEO_OV1063X) += ov1063x.o
51obj-$(CONFIG_VIDEO_TVP5158) += tvp5158.o
51obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o 52obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
52obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 53obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
53obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o 54obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
diff --git a/drivers/media/i2c/tvp5158.c b/drivers/media/i2c/tvp5158.c
new file mode 100644
index 00000000000..674fefa367c
--- /dev/null
+++ b/drivers/media/i2c/tvp5158.c
@@ -0,0 +1,672 @@
1#include <linux/delay.h>
2#include <linux/i2c.h>
3#include <linux/gpio.h>
4#include <linux/init.h>
5#include <linux/module.h>
6#include <linux/regulator/consumer.h>
7#include <linux/regmap.h>
8#include <linux/slab.h>
9#include <linux/v4l2-mediabus.h>
10#include <linux/videodev2.h>
11
12#include <media/soc_camera.h>
13#include <media/v4l2-async.h>
14#include <media/v4l2-chip-ident.h>
15#include <media/v4l2-common.h>
16#include <media/v4l2-ctrls.h>
17
18#include <linux/pm_runtime.h>
19
20#include <linux/of_gpio.h>
21#include <linux/of_i2c.h>
22#include <linux/of_device.h>
23
24/* Debug functions */
25static bool debug;
26module_param(debug, bool, 0644);
27MODULE_PARM_DESC(debug, "Debug level (0-2)");
28
29/* VBUS Register Address (24-bit), VBUS Register value (8-bit) */
30struct vbus_addr_value {
31 unsigned int addr;
32 unsigned char val;
33};
34
35struct vbus_addr_value vbus_addr_value_set[] = {
36 {0x00403E50, 0x40},
37 {0x00403E51, 0x00},
38 {0x00403E52, 0x40},
39 {0x00403E53, 0x00},
40 {0x00403E54, 0x44},
41 {0x00403E55, 0x23},
42 {0x00403E56, 0x38},
43 {0x00403E57, 0x10},
44 {0x00403E58, 0x53},
45 {0x00403E59, 0x23},
46 {0x00403E5A, 0x02},
47 {0x00403E5B, 0x00},
48 {0x00403E5C, 0x20},
49 {0x00403E5D, 0x00},
50 {0x00403E5E, 0x04},
51 {0x00403E5F, 0x04},
52 {0x00403E60, 0x04},
53 {0x00403E61, 0x04},
54 {0x00403E62, 0x10},
55 {0x00403E63, 0xF8},
56 {0x00403E64, 0x30},
57 {0x00403E65, 0x20},
58 {0x00403E66, 0x30},
59 {0x00403E67, 0x3F},
60 {0x00403E68, 0x3F},
61 {0x00403E69, 0x3F},
62 {0x00403E6A, 0x0C},
63 {0x00403E6B, 0x0C},
64 {0x00403E6C, 0x80},
65 {0x00403E6D, 0x80},
66 {0x00403E6E, 0x08},
67 {0x00403E6F, 0x08},
68 {0x00403E70, 0x08},
69 {0x00403E71, 0x30},
70 {0x00403E72, 0x08},
71 {0x00403E73, 0x04},
72 {0x00403E74, 0x00},
73 {0x00403E75, 0x10},
74 {0x00403E76, 0x00},
75 {0x00403E77, 0x00},
76 {0x00403E78, 0x38},
77 {0x00403E79, 0x00},
78 {0x00403E7A, 0x55},
79 {0x00403E7B, 0x03},
80 {0x00403E7C, 0x03},
81 {0x00403E7D, 0x00},
82 {0x00403E7E, 0x03},
83 {0x00403E7F, 0x00},
84 {0x00403E80, 0x30},
85 {0x00403E81, 0x30},
86 {0x00403E82, 0x18},
87 {0x00403E83, 0x0C},
88 {0x00403E95, 0x00},
89 {0x00403E96, 0x00},
90 {0x00403E9B, 0x3F},
91 {0x00403EA2, 0x0C},
92 {0x00403EA3, 0x10},
93 {0x00403EA6, 0x0C},
94 {0x00403EA7, 0x10},
95 {0x00403EA8, 0x44},
96 {0x00403EA9, 0x00},
97};
98static bool vbus_prog = 1;
99static int
100tvp5158_get_gpios(struct device_node *node, struct i2c_client *client);
101static int tvp5158_set_gpios(struct i2c_client *client);
102static int
103tvp5158_set_default(struct i2c_client *client, unsigned char core);
104static enum tvp5158_std
105tvp5158_get_video_std(struct i2c_client *client, unsigned char core);
106static void
107tvp5158_start_streaming(struct i2c_client *client, unsigned char core);
108static int
109tvp5158_set_int_regs(struct i2c_client *client, struct vbus_addr_value *reg,
110 int cnt);
111
112#define REG_STAUS_1 0x00
113#define REG_STAUS_2 0x01
114#define REG_VID_STAND 0x0C
115#define REG_CHIPID_MSB 0x08
116#define REG_CHIPID_LSB 0x09
117#define REG_AVD_CTRL_1 0xB0
118#define REG_AVD_CTRL_2 0xB1
119#define REG_OFM_CTRL 0xB2
120#define REG_DEC_RD_EN 0xFF
121#define REG_DEC_WR_EN 0xFE
122#define REG_VBUS_1 0xE8
123#define REG_VBUS_2 0xE9
124#define REG_VBUS_3 0xEA
125#define REG_VBUS_DATA 0xE0
126
127#define TVP_CORE_ALL 0x0F
128#define TVP_DECODER_1 (1<<0)
129/* Non interleaved */
130#define TVP_INTERLEAVE_MODE_NON (0<<6)
131/* Number of time multiplexed channels = 0 */
132#define TVP_CH_MUX_NUMBER (2<<4)
133/* ITU BT 656 8 bit */
134#define TVP_OUTPUT_TYPE (0<<3)
135/* Single stage */
136#define TVP_VCS_ID (0<<2)
137/* D1 */
138#define TVP_VID_RES (0<<0)
139
140#define TVP_ENABLE_DITHERING (1<<4)
141#define TVP_VID_DET_SAVEAV_EN (1<<0)
142
143#define TVP_VIDEO_PORT_ENABLE (1<<0)
144#define TVP_OUT_CLK_P_EN (1<<2)
145#define TVP_FIELD_RATE (1<<5)
146#define TVP_SIGNAL_PRESENT (1<<7)
147#define TVP_VIDEO_STANDARD_MASK (0x07)
148
149/* Number of pixels and number of lines per frame for different standards */
150#define NTSC_NUM_ACTIVE_PIXELS (720)
151#define NTSC_NUM_ACTIVE_LINES (480)
152
153struct tvp5158_color_format {
154 enum v4l2_mbus_pixelcode code;
155 enum v4l2_colorspace colorspace;
156};
157
158static const struct tvp5158_color_format tvp5158_cfmts[] = {
159 {
160 .code = V4L2_MBUS_FMT_YUYV8_2X8,
161 .colorspace = V4L2_COLORSPACE_SMPTE170M,
162 },
163 {
164 .code = V4L2_MBUS_FMT_YUYV10_2X10,
165 .colorspace = V4L2_COLORSPACE_SMPTE170M,
166 },
167};
168
169/* enum tvp5158_std - enum for supported standards */
170enum tvp5158_std {
171 STD_NTSC_MJ = 0,
172 STD_PAL_BDGHIN,
173 STD_INVALID
174};
175
176/**
177 * struct tvp5158_std_info - Structure to store standard informations
178 * @width: Line width in pixels
179 * @height:Number of active lines
180 * @standard: v4l2 standard structure information
181 */
182struct tvp5158_std_info {
183 unsigned long width;
184 unsigned long height;
185 struct v4l2_standard standard;
186};
187
188enum tvp5158_signal_present {
189 TVP5158_SIGNAL_DEAD = 0,
190 TVP5158_SIGNAL_PRESENT
191};
192struct tvp5158_priv {
193 struct v4l2_subdev subdev;
194 struct v4l2_async_subdev asd;
195 struct v4l2_async_subdev_list asdl;
196 struct v4l2_ctrl_handler hdl;
197 int power;
198 int model;
199 int revision;
200 int width;
201 int height;
202 const char *sensor_name;
203 int cam_fpd_mux_s0_gpio;
204 int sel_tvp_fpd_s0;
205 enum tvp5158_std current_std;
206 enum tvp5158_signal_present signal_present;
207 const struct tvp5158_std_info *std_list;
208 const struct tvp5158_color_format *cfmt;
209};
210
211static const struct tvp5158_std_info tvp5158_std_list[] = {
212/* Standard: STD_NTSC_MJ */
213[STD_NTSC_MJ] = {
214 .width = NTSC_NUM_ACTIVE_PIXELS,
215 .height = NTSC_NUM_ACTIVE_LINES,
216 .standard = {
217 .index = 0,
218 .id = V4L2_STD_NTSC,
219 .name = "NTSC",
220 .frameperiod = {1001, 30000},
221 .framelines = 525
222 },
223 },
224 /* Standard: need to add for additional standard */
225};
226
227static struct tvp5158_priv *to_tvp5158(const struct i2c_client *client)
228{
229 return container_of(i2c_get_clientdata(client), struct tvp5158_priv,
230 subdev);
231}
232
233
234static int tvp5158_read(struct i2c_client *client, unsigned char addr)
235{
236 unsigned char buffer[1];
237 int rc;
238
239 buffer[0] = addr;
240
241 rc = i2c_master_send(client, buffer, 1);
242 if (rc < 0) {
243 dev_err(&client->dev, "i2c i/o error: rc == %d (should be 1)\n"
244 , rc);
245 return rc;
246 }
247
248 rc = i2c_master_recv(client, buffer, 1);
249 if (rc < 0) {
250 dev_err(&client->dev, "i2c i/o error: rc == %d (should be 1)\n"
251 , rc);
252 return rc;
253 }
254
255 return buffer[0];
256}
257static inline void tvp5158_write(struct i2c_client *client, unsigned char addr,
258 unsigned char value)
259{
260 unsigned char buffer[2];
261 int rc;
262
263 buffer[0] = addr;
264 buffer[1] = value;
265 rc = i2c_master_send(client, buffer, 2);
266 if (rc != 2)
267 dev_err(&client->dev, "i2c i/o error: rc == %d (should be 2)\n"
268 , rc);
269}
270
271/**
272 * tvp5158_s_stream() - V4L2 decoder i/f handler for s_stream
273 * @sd: pointer to standard V4L2 sub-device structure
274 * @enable: streaming enable or disable
275 *
276 * Sets streaming to enable or disable.
277 */
278static int tvp5158_s_stream(struct v4l2_subdev *sd, int enable)
279{
280 struct i2c_client *client = v4l2_get_subdevdata(sd);
281 if (enable) {
282 if (vbus_prog == 1)
283 /* VBUS address value setting */
284 tvp5158_set_int_regs(client, vbus_addr_value_set,
285 ARRAY_SIZE(vbus_addr_value_set));
286 tvp5158_start_streaming(client, TVP_DECODER_1);
287 } else {
288 tvp5158_write(client, REG_OFM_CTRL, 0x0);
289 }
290
291 return 0;
292}
293
294/**
295 * tvp5158_querystd() - V4L2 decoder interface handler for querystd
296 * @sd: pointer to standard V4L2 sub-device structure
297 * @std_id: standard V4L2 std_id ioctl enum
298 *
299 * Returns the current standard detected by TVP5146/47. If no active input is
300 * detected then *std_id is set to 0 and the function returns 0.
301 */
302static int tvp5158_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
303{
304 struct i2c_client *client = v4l2_get_subdevdata(sd);
305 struct tvp5158_priv *priv = to_tvp5158(client);
306
307 if (std_id == NULL)
308 return -EINVAL;
309 *std_id = V4L2_STD_UNKNOWN;
310
311 tvp5158_get_video_std(client, TVP_DECODER_1);
312 if (priv->current_std == STD_INVALID)
313 return -EINVAL;
314 *std_id = priv->std_list[0].standard.id;
315
316return 0;
317}
318
319/**
320 * tvp5158_g_parm() - V4L2 decoder interface handler for g_parm
321 * @sd: pointer to standard V4L2 sub-device structure
322 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
323 *
324 * Returns the decoder's video CAPTURE parameters.
325 */
326static int tvp5158_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
327{
328 struct i2c_client *client = v4l2_get_subdevdata(sd);
329 struct tvp5158_priv *priv = to_tvp5158(client);
330 struct v4l2_captureparm *cparm;
331 enum tvp5158_std current_std;
332
333 if (parms == NULL)
334 return -EINVAL;
335
336 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
337 /* only capture is supported */
338 return -EINVAL;
339 tvp5158_set_default(client, TVP_DECODER_1);
340 tvp5158_get_video_std(client, TVP_DECODER_1);
341 if (priv->current_std == STD_INVALID)
342 return -EINVAL;
343 /* get the current standard */
344 current_std = priv->current_std;
345 cparm = &parms->parm.capture;
346 cparm->capability = V4L2_CAP_TIMEPERFRAME;
347 cparm->timeperframe =
348 priv->std_list[current_std].standard.frameperiod;
349
350 return 0;
351}
352
353/**
354 * tvp5158_s_parm() - V4L2 decoder interface handler for s_parm
355 * @sd: pointer to standard V4L2 sub-device structure
356 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
357 *
358 * Configures the decoder to use the input parameters, if possible. If
359 * not possible, returns the appropriate error code.
360 */
361static int tvp5158_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
362{
363 struct i2c_client *client = v4l2_get_subdevdata(sd);
364 struct tvp5158_priv *priv = to_tvp5158(client);
365 struct v4l2_fract *timeperframe;
366 enum tvp5158_std current_std;
367
368 if (parms == NULL)
369 return -EINVAL;
370
371 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
372 /* only capture is supported */
373 return -EINVAL;
374
375 timeperframe = &parms->parm.capture.timeperframe;
376
377 /* get the current standard */
378 current_std = priv->current_std;
379
380 *timeperframe =
381 priv->std_list[current_std].standard.frameperiod;
382
383 return 0;
384}
385
386/* set the format we will capture in */
387static int tvp5158_s_fmt(struct v4l2_subdev *sd,
388 struct v4l2_mbus_framefmt *mf)
389{
390 struct i2c_client *client = v4l2_get_subdevdata(sd);
391 struct tvp5158_priv *priv = to_tvp5158(client);
392
393 tvp5158_set_gpios(client);
394 v4l2_info(&priv->subdev, "Currently only D1 resolution is supported\n");
395
396 return 0;
397}
398
399static int tvp5158_g_fmt(struct v4l2_subdev *sd,
400 struct v4l2_mbus_framefmt *mf)
401{
402 struct i2c_client *client = v4l2_get_subdevdata(sd);
403 struct tvp5158_priv *priv = to_tvp5158(client);
404 enum tvp5158_std current_std;
405
406 tvp5158_set_default(client, TVP_DECODER_1);
407 tvp5158_get_video_std(client, TVP_DECODER_1);
408
409 if (priv->current_std == STD_INVALID)
410 return -EINVAL;
411 /* Calculate height and width based on current standard */
412 current_std = priv->current_std;
413 /* both fields alternating into separate buffers */
414 mf->field = V4L2_FIELD_ALTERNATE;
415 mf->code = tvp5158_cfmts[0].code;
416 mf->width = priv->std_list[current_std].width;
417 mf->height = priv->std_list[current_std].height;
418 mf->colorspace = tvp5158_cfmts[0].colorspace;
419
420 return 0;
421}
422
423static int tvp5158_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
424 enum v4l2_mbus_pixelcode *code)
425{
426 if (index >= ARRAY_SIZE(tvp5158_cfmts))
427 return -EINVAL;
428
429 *code = tvp5158_cfmts[0].code;
430
431 return 0;
432}
433
434static int tvp5158_get_gpios(struct device_node *node,
435 struct i2c_client *client)
436{
437
438 struct tvp5158_priv *priv = to_tvp5158(client);
439 int gpio;
440
441 gpio = of_get_gpio(node, 0);
442 if (gpio_is_valid(gpio)) {
443 priv->cam_fpd_mux_s0_gpio = gpio;
444 } else {
445 dev_err(&client->dev, "failed to parse CAM_FPD_MUX_S0 gpio\n");
446 return -EINVAL;
447 }
448 gpio = of_get_gpio(node, 1);
449 if (gpio_is_valid(gpio)) {
450 priv->sel_tvp_fpd_s0 = gpio;
451 } else {
452 dev_err(&client->dev, "failed to parse TVP_FPD_MUX_S0 gpio\n");
453 return -EINVAL;
454 }
455
456 return 0;
457}
458
459static int tvp5158_set_gpios(struct i2c_client *client)
460{
461
462 struct tvp5158_priv *priv = to_tvp5158(client);
463 struct gpio gpios[] = {
464 { priv->sel_tvp_fpd_s0, GPIOF_OUT_INIT_LOW,
465 "tvp_fpd_mux_s0" },
466 { priv->cam_fpd_mux_s0_gpio, GPIOF_OUT_INIT_HIGH,
467 "cam_fpd_mux_s0" },
468 };
469 int ret = -1;
470
471 ret = gpio_request_array(gpios, ARRAY_SIZE(gpios));
472 if (ret)
473 return ret;
474
475 gpio_free_array(gpios, ARRAY_SIZE(gpios));
476
477 return 0;
478}
479
480static struct v4l2_subdev_video_ops tvp5158_video_ops = {
481 .querystd = tvp5158_querystd,
482 .enum_mbus_fmt = tvp5158_enum_fmt,
483 .g_parm = tvp5158_g_parm,
484 .s_parm = tvp5158_s_parm,
485 .s_stream = tvp5158_s_stream,
486 .g_mbus_fmt = tvp5158_g_fmt,
487 .s_mbus_fmt = tvp5158_s_fmt,
488 .try_mbus_fmt = tvp5158_g_fmt,
489};
490
491static struct v4l2_subdev_ops tvp5158_subdev_ops = {
492 .video = &tvp5158_video_ops,
493};
494
495static const struct i2c_device_id tvp5158_id[] = {
496 { "ti,tvp5158", 0 },
497 { }
498};
499MODULE_DEVICE_TABLE(i2c, tvp5158_id);
500
501static const struct of_device_id tvp5158_dt_id[] = {
502 {
503 .compatible = "ti,tvp5158", .data = "tvp5158"
504 },
505 {
506 }
507};
508
509static int tvp5158_set_int_regs(struct i2c_client *client,
510 struct vbus_addr_value *reg, int cnt)
511{
512 int i = 0;
513 /* Core Write enable*/
514 tvp5158_write(client, REG_DEC_WR_EN, TVP_DECODER_1);
515 for (i = 0; i < cnt; i++) {
516 tvp5158_write(client, REG_VBUS_1, ((reg[i].addr >> 0) & 0xFF));
517 tvp5158_write(client, REG_VBUS_2, ((reg[i].addr >> 8) & 0xFF));
518 tvp5158_write(client, REG_VBUS_3, ((reg[i].addr >> 16) & 0xFF));
519 tvp5158_write(client, REG_VBUS_DATA, reg[i].val);
520 }
521 vbus_prog = 0;
522 return 0;
523}
524
525static int
526tvp5158_set_default(struct i2c_client *client, unsigned char core)
527{
528 unsigned char tvp_reg_val = 0;
529 /* Core Write enable*/
530 tvp5158_write(client, REG_DEC_WR_EN, core);
531 /* Set Video format */
532 tvp_reg_val = TVP_INTERLEAVE_MODE_NON | TVP_CH_MUX_NUMBER
533 | TVP_OUTPUT_TYPE | TVP_VCS_ID | TVP_VID_RES;
534 tvp5158_write(client, REG_AVD_CTRL_1, tvp_reg_val);
535 tvp_reg_val = 0;
536 tvp_reg_val = TVP_ENABLE_DITHERING | TVP_VID_DET_SAVEAV_EN;
537 tvp5158_write(client, REG_AVD_CTRL_2, tvp_reg_val);
538
539 return 0;
540}
541
542static enum tvp5158_std
543tvp5158_get_video_std(struct i2c_client *client, unsigned char core)
544{
545 struct tvp5158_priv *priv = to_tvp5158(client);
546 int i2c_read = 0, ret = 0;
547
548 /* Core Read Enable */
549 tvp5158_write(client, REG_DEC_RD_EN, core);
550 /* Get Video Status */
551 i2c_read = tvp5158_read(client, REG_STAUS_2);
552 v4l2_dbg(1, debug, &priv->subdev, "%s\n",
553 (i2c_read & TVP_SIGNAL_PRESENT) ?
554 "Signal Present" : "Signal not present");
555 if (i2c_read & TVP_SIGNAL_PRESENT)
556 priv->signal_present = TVP5158_SIGNAL_PRESENT;
557 else {
558 priv->current_std = STD_INVALID;
559 return priv->current_std;
560 }
561 /* Get Video Standard */
562 ret = tvp5158_read(client, REG_VID_STAND);
563 i2c_read = tvp5158_read(client, REG_STAUS_1);
564 v4l2_dbg(1, debug, &priv->subdev, "Video Standard : %s %dHz\n",
565 (ret & TVP_VIDEO_STANDARD_MASK) == 1 ?
566 "NTSC 720x240 @" : "Unknown",
567 (i2c_read & TVP_FIELD_RATE) ? 50 : 60);
568 if (ret & TVP_VIDEO_STANDARD_MASK) {
569 priv->std_list = tvp5158_std_list;
570 priv->current_std = STD_NTSC_MJ;
571 } else
572 priv->current_std = STD_INVALID;
573
574 return priv->current_std;
575}
576
577static void
578tvp5158_start_streaming(struct i2c_client *client, unsigned char core)
579{
580 unsigned char tvp_reg_val = 0;
581
582 /* Decoder Write Enable */
583 tvp5158_write(client, REG_DEC_WR_EN, core);
584 /* Enable output stream on */
585 tvp_reg_val = TVP_VIDEO_PORT_ENABLE | TVP_OUT_CLK_P_EN ;
586 tvp5158_write(client, REG_OFM_CTRL, tvp_reg_val);
587
588}
589
590static int tvp5158_probe(struct i2c_client *client,
591 const struct i2c_device_id *did)
592{
593 struct tvp5158_priv *priv;
594 struct v4l2_subdev *sd;
595 struct device_node *node = client->dev.of_node;
596 int ret = -1;
597 int i2c_read;
598 union {
599 char buff[4];
600 int buffer;
601 } u_i2cbuf;
602
603 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
604 if (!priv)
605 return -ENOMEM;
606 i2c_set_clientdata(client, priv);
607
608 priv->cfmt = &tvp5158_cfmts[0];
609
610 sd = &priv->subdev;
611
612 v4l2_i2c_subdev_init(sd, client, &tvp5158_subdev_ops);
613
614 ret = tvp5158_get_gpios(node, client);
615 if (ret) {
616 dev_err(&client->dev, "Unable to get gpios\n");
617 return ret;
618 }
619
620 ret = tvp5158_set_gpios(client);
621 if (ret) {
622 dev_err(&client->dev, "failed to set gpios ERR %d\n", ret);
623 return ret;
624 }
625
626 priv->signal_present = TVP5158_SIGNAL_DEAD;
627 priv->current_std = STD_INVALID;
628 /* Get Chip ID and register with v4l2*/
629 i2c_read = tvp5158_read(client, REG_CHIPID_MSB);
630 u_i2cbuf.buffer = i2c_read << 8;
631 i2c_read = tvp5158_read(client, REG_CHIPID_LSB);
632 u_i2cbuf.buffer |= i2c_read;
633 if (u_i2cbuf.buffer == 0x5158) {
634 v4l2_dbg(1, debug, sd, "Chip id : %x\n", u_i2cbuf.buffer);
635 tvp5158_write(client, REG_DEC_WR_EN, TVP_DECODER_1);
636 tvp5158_write(client, REG_OFM_CTRL,
637 (TVP_VIDEO_PORT_ENABLE | TVP_OUT_CLK_P_EN));
638 /* V4l2 asyn subdev register */
639 sd->dev = &client->dev;
640 ret = v4l2_async_register_subdev(sd);
641 if (!ret)
642 v4l2_info(&priv->subdev, "Camera sensor driver registered\n");
643 pm_runtime_enable(&client->dev);
644 }
645
646 return ret;
647}
648
649static int tvp5158_remove(struct i2c_client *client)
650{
651 struct tvp5158_priv *priv = i2c_get_clientdata(client);
652
653 v4l2_device_unregister_subdev(&priv->subdev);
654 return 0;
655}
656
657static struct i2c_driver tvp5158_i2c_driver = {
658 .driver = {
659 .owner = THIS_MODULE,
660 .name = "tvp5158",
661 .of_match_table = tvp5158_dt_id,
662 },
663 .probe = tvp5158_probe,
664 .remove = tvp5158_remove,
665 .id_table = tvp5158_id,
666};
667
668module_i2c_driver(tvp5158_i2c_driver);
669
670MODULE_DESCRIPTION("Video Decoder driver");
671MODULE_AUTHOR("Sathishkumar S");
672MODULE_LICENSE("GPL v2");