diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2009-01-12 04:17:43 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:51 -0400 |
commit | 6722e0ef1f72d86169b2b0f96ad34afd225cd080 (patch) | |
tree | ce57e41c5f999b34a3c8a8255c8250a8eef8d36a /drivers | |
parent | df7fa09cca9d80f746c29f95b09a7223f6c2f4e7 (diff) |
V4L/DVB (10655): tvp514x: make the module aware of rich people
because they might design two of those chips on a single board.
You never know.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/tvp514x.c | 106 |
1 files changed, 60 insertions, 46 deletions
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 5f4cbc2b23c1..f0b2b8ed2fe4 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c | |||
@@ -86,9 +86,12 @@ struct tvp514x_std_info { | |||
86 | struct v4l2_standard standard; | 86 | struct v4l2_standard standard; |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static struct tvp514x_reg tvp514x_reg_list_default[0x40]; | ||
89 | /** | 90 | /** |
90 | * struct tvp514x_decoded - TVP5146/47 decoder object | 91 | * struct tvp514x_decoder - TVP5146/47 decoder object |
91 | * @v4l2_int_device: Slave handle | 92 | * @v4l2_int_device: Slave handle |
93 | * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device | ||
94 | * @tvp514x_regs: copy of hw's regs with preset values. | ||
92 | * @pdata: Board specific | 95 | * @pdata: Board specific |
93 | * @client: I2C client data | 96 | * @client: I2C client data |
94 | * @id: Entry from I2C table | 97 | * @id: Entry from I2C table |
@@ -103,7 +106,9 @@ struct tvp514x_std_info { | |||
103 | * @route: input and output routing at chip level | 106 | * @route: input and output routing at chip level |
104 | */ | 107 | */ |
105 | struct tvp514x_decoder { | 108 | struct tvp514x_decoder { |
106 | struct v4l2_int_device *v4l2_int_device; | 109 | struct v4l2_int_device v4l2_int_device; |
110 | struct v4l2_int_slave tvp514x_slave; | ||
111 | struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; | ||
107 | const struct tvp514x_platform_data *pdata; | 112 | const struct tvp514x_platform_data *pdata; |
108 | struct i2c_client *client; | 113 | struct i2c_client *client; |
109 | 114 | ||
@@ -124,7 +129,7 @@ struct tvp514x_decoder { | |||
124 | }; | 129 | }; |
125 | 130 | ||
126 | /* TVP514x default register values */ | 131 | /* TVP514x default register values */ |
127 | static struct tvp514x_reg tvp514x_reg_list[] = { | 132 | static struct tvp514x_reg tvp514x_reg_list_default[] = { |
128 | {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ | 133 | {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ |
129 | {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, | 134 | {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, |
130 | {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ | 135 | {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ |
@@ -422,7 +427,7 @@ static int tvp514x_configure(struct tvp514x_decoder *decoder) | |||
422 | 427 | ||
423 | /* common register initialization */ | 428 | /* common register initialization */ |
424 | err = | 429 | err = |
425 | tvp514x_write_regs(decoder->client, tvp514x_reg_list); | 430 | tvp514x_write_regs(decoder->client, decoder->tvp514x_regs); |
426 | if (err) | 431 | if (err) |
427 | return err; | 432 | return err; |
428 | 433 | ||
@@ -580,7 +585,8 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) | |||
580 | return err; | 585 | return err; |
581 | 586 | ||
582 | decoder->current_std = i; | 587 | decoder->current_std = i; |
583 | tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std; | 588 | decoder->tvp514x_regs[REG_VIDEO_STD].val = |
589 | decoder->std_list[i].video_std; | ||
584 | 590 | ||
585 | v4l_dbg(1, debug, decoder->client, "Standard set to: %s", | 591 | v4l_dbg(1, debug, decoder->client, "Standard set to: %s", |
586 | decoder->std_list[i].standard.name); | 592 | decoder->std_list[i].standard.name); |
@@ -625,8 +631,8 @@ static int ioctl_s_routing(struct v4l2_int_device *s, | |||
625 | if (err) | 631 | if (err) |
626 | return err; | 632 | return err; |
627 | 633 | ||
628 | tvp514x_reg_list[REG_INPUT_SEL].val = input_sel; | 634 | decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel; |
629 | tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel; | 635 | decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel; |
630 | 636 | ||
631 | /* Clear status */ | 637 | /* Clear status */ |
632 | msleep(LOCK_RETRY_DELAY); | 638 | msleep(LOCK_RETRY_DELAY); |
@@ -779,16 +785,16 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
779 | 785 | ||
780 | switch (ctrl->id) { | 786 | switch (ctrl->id) { |
781 | case V4L2_CID_BRIGHTNESS: | 787 | case V4L2_CID_BRIGHTNESS: |
782 | ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val; | 788 | ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val; |
783 | break; | 789 | break; |
784 | case V4L2_CID_CONTRAST: | 790 | case V4L2_CID_CONTRAST: |
785 | ctrl->value = tvp514x_reg_list[REG_CONTRAST].val; | 791 | ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val; |
786 | break; | 792 | break; |
787 | case V4L2_CID_SATURATION: | 793 | case V4L2_CID_SATURATION: |
788 | ctrl->value = tvp514x_reg_list[REG_SATURATION].val; | 794 | ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val; |
789 | break; | 795 | break; |
790 | case V4L2_CID_HUE: | 796 | case V4L2_CID_HUE: |
791 | ctrl->value = tvp514x_reg_list[REG_HUE].val; | 797 | ctrl->value = decoder->tvp514x_regs[REG_HUE].val; |
792 | if (ctrl->value == 0x7F) | 798 | if (ctrl->value == 0x7F) |
793 | ctrl->value = 180; | 799 | ctrl->value = 180; |
794 | else if (ctrl->value == 0x80) | 800 | else if (ctrl->value == 0x80) |
@@ -798,7 +804,7 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
798 | 804 | ||
799 | break; | 805 | break; |
800 | case V4L2_CID_AUTOGAIN: | 806 | case V4L2_CID_AUTOGAIN: |
801 | ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val; | 807 | ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val; |
802 | if ((ctrl->value & 0x3) == 3) | 808 | if ((ctrl->value & 0x3) == 3) |
803 | ctrl->value = 1; | 809 | ctrl->value = 1; |
804 | else | 810 | else |
@@ -848,7 +854,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
848 | value); | 854 | value); |
849 | if (err) | 855 | if (err) |
850 | return err; | 856 | return err; |
851 | tvp514x_reg_list[REG_BRIGHTNESS].val = value; | 857 | decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; |
852 | break; | 858 | break; |
853 | case V4L2_CID_CONTRAST: | 859 | case V4L2_CID_CONTRAST: |
854 | if (ctrl->value < 0 || ctrl->value > 255) { | 860 | if (ctrl->value < 0 || ctrl->value > 255) { |
@@ -861,7 +867,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
861 | value); | 867 | value); |
862 | if (err) | 868 | if (err) |
863 | return err; | 869 | return err; |
864 | tvp514x_reg_list[REG_CONTRAST].val = value; | 870 | decoder->tvp514x_regs[REG_CONTRAST].val = value; |
865 | break; | 871 | break; |
866 | case V4L2_CID_SATURATION: | 872 | case V4L2_CID_SATURATION: |
867 | if (ctrl->value < 0 || ctrl->value > 255) { | 873 | if (ctrl->value < 0 || ctrl->value > 255) { |
@@ -874,7 +880,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
874 | value); | 880 | value); |
875 | if (err) | 881 | if (err) |
876 | return err; | 882 | return err; |
877 | tvp514x_reg_list[REG_SATURATION].val = value; | 883 | decoder->tvp514x_regs[REG_SATURATION].val = value; |
878 | break; | 884 | break; |
879 | case V4L2_CID_HUE: | 885 | case V4L2_CID_HUE: |
880 | if (value == 180) | 886 | if (value == 180) |
@@ -893,7 +899,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
893 | value); | 899 | value); |
894 | if (err) | 900 | if (err) |
895 | return err; | 901 | return err; |
896 | tvp514x_reg_list[REG_HUE].val = value; | 902 | decoder->tvp514x_regs[REG_HUE].val = value; |
897 | break; | 903 | break; |
898 | case V4L2_CID_AUTOGAIN: | 904 | case V4L2_CID_AUTOGAIN: |
899 | if (value == 1) | 905 | if (value == 1) |
@@ -910,7 +916,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
910 | value); | 916 | value); |
911 | if (err) | 917 | if (err) |
912 | return err; | 918 | return err; |
913 | tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value; | 919 | decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; |
914 | break; | 920 | break; |
915 | default: | 921 | default: |
916 | v4l_err(decoder->client, | 922 | v4l_err(decoder->client, |
@@ -1275,7 +1281,7 @@ static int ioctl_init(struct v4l2_int_device *s) | |||
1275 | struct tvp514x_decoder *decoder = s->priv; | 1281 | struct tvp514x_decoder *decoder = s->priv; |
1276 | 1282 | ||
1277 | /* Set default standard to auto */ | 1283 | /* Set default standard to auto */ |
1278 | tvp514x_reg_list[REG_VIDEO_STD].val = | 1284 | decoder->tvp514x_regs[REG_VIDEO_STD].val = |
1279 | VIDEO_STD_AUTO_SWITCH_BIT; | 1285 | VIDEO_STD_AUTO_SWITCH_BIT; |
1280 | 1286 | ||
1281 | return tvp514x_configure(decoder); | 1287 | return tvp514x_configure(decoder); |
@@ -1344,11 +1350,6 @@ static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = { | |||
1344 | (v4l2_int_ioctl_func *) ioctl_s_routing}, | 1350 | (v4l2_int_ioctl_func *) ioctl_s_routing}, |
1345 | }; | 1351 | }; |
1346 | 1352 | ||
1347 | static struct v4l2_int_slave tvp514x_slave = { | ||
1348 | .ioctls = tvp514x_ioctl_desc, | ||
1349 | .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), | ||
1350 | }; | ||
1351 | |||
1352 | static struct tvp514x_decoder tvp514x_dev = { | 1353 | static struct tvp514x_decoder tvp514x_dev = { |
1353 | .state = STATE_NOT_DETECTED, | 1354 | .state = STATE_NOT_DETECTED, |
1354 | 1355 | ||
@@ -1369,17 +1370,15 @@ static struct tvp514x_decoder tvp514x_dev = { | |||
1369 | .current_std = STD_NTSC_MJ, | 1370 | .current_std = STD_NTSC_MJ, |
1370 | .std_list = tvp514x_std_list, | 1371 | .std_list = tvp514x_std_list, |
1371 | .num_stds = ARRAY_SIZE(tvp514x_std_list), | 1372 | .num_stds = ARRAY_SIZE(tvp514x_std_list), |
1372 | 1373 | .v4l2_int_device = { | |
1373 | }; | 1374 | .module = THIS_MODULE, |
1374 | 1375 | .name = TVP514X_MODULE_NAME, | |
1375 | static struct v4l2_int_device tvp514x_int_device = { | 1376 | .type = v4l2_int_type_slave, |
1376 | .module = THIS_MODULE, | 1377 | }, |
1377 | .name = TVP514X_MODULE_NAME, | 1378 | .tvp514x_slave = { |
1378 | .priv = &tvp514x_dev, | 1379 | .ioctls = tvp514x_ioctl_desc, |
1379 | .type = v4l2_int_type_slave, | 1380 | .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), |
1380 | .u = { | 1381 | }, |
1381 | .slave = &tvp514x_slave, | ||
1382 | }, | ||
1383 | }; | 1382 | }; |
1384 | 1383 | ||
1385 | /** | 1384 | /** |
@@ -1392,26 +1391,37 @@ static struct v4l2_int_device tvp514x_int_device = { | |||
1392 | static int | 1391 | static int |
1393 | tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1392 | tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) |
1394 | { | 1393 | { |
1395 | struct tvp514x_decoder *decoder = &tvp514x_dev; | 1394 | struct tvp514x_decoder *decoder; |
1396 | int err; | 1395 | int err; |
1397 | 1396 | ||
1398 | /* Check if the adapter supports the needed features */ | 1397 | /* Check if the adapter supports the needed features */ |
1399 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1398 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1400 | return -EIO; | 1399 | return -EIO; |
1401 | 1400 | ||
1402 | decoder->pdata = client->dev.platform_data; | 1401 | decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); |
1403 | if (!decoder->pdata) { | 1402 | if (!decoder) |
1403 | return -ENOMEM; | ||
1404 | |||
1405 | if (!client->dev.platform_data) { | ||
1404 | v4l_err(client, "No platform data!!\n"); | 1406 | v4l_err(client, "No platform data!!\n"); |
1405 | return -ENODEV; | 1407 | err = -ENODEV; |
1408 | goto out_free; | ||
1406 | } | 1409 | } |
1410 | |||
1411 | *decoder = tvp514x_dev; | ||
1412 | decoder->v4l2_int_device.priv = decoder; | ||
1413 | decoder->pdata = client->dev.platform_data; | ||
1414 | decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave; | ||
1415 | memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, | ||
1416 | sizeof(tvp514x_reg_list_default)); | ||
1407 | /* | 1417 | /* |
1408 | * Fetch platform specific data, and configure the | 1418 | * Fetch platform specific data, and configure the |
1409 | * tvp514x_reg_list[] accordingly. Since this is one | 1419 | * tvp514x_reg_list[] accordingly. Since this is one |
1410 | * time configuration, no need to preserve. | 1420 | * time configuration, no need to preserve. |
1411 | */ | 1421 | */ |
1412 | tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |= | 1422 | decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= |
1413 | (decoder->pdata->clk_polarity << 1); | 1423 | (decoder->pdata->clk_polarity << 1); |
1414 | tvp514x_reg_list[REG_SYNC_CONTROL].val |= | 1424 | decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= |
1415 | ((decoder->pdata->hs_polarity << 2) | | 1425 | ((decoder->pdata->hs_polarity << 2) | |
1416 | (decoder->pdata->vs_polarity << 3)); | 1426 | (decoder->pdata->vs_polarity << 3)); |
1417 | /* | 1427 | /* |
@@ -1419,23 +1429,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1419 | */ | 1429 | */ |
1420 | decoder->id = (struct i2c_device_id *)id; | 1430 | decoder->id = (struct i2c_device_id *)id; |
1421 | /* Attach to Master */ | 1431 | /* Attach to Master */ |
1422 | strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master); | 1432 | strcpy(decoder->v4l2_int_device.u.slave->attach_to, |
1423 | decoder->v4l2_int_device = &tvp514x_int_device; | 1433 | decoder->pdata->master); |
1424 | decoder->client = client; | 1434 | decoder->client = client; |
1425 | i2c_set_clientdata(client, decoder); | 1435 | i2c_set_clientdata(client, decoder); |
1426 | 1436 | ||
1427 | /* Register with V4L2 layer as slave device */ | 1437 | /* Register with V4L2 layer as slave device */ |
1428 | err = v4l2_int_device_register(decoder->v4l2_int_device); | 1438 | err = v4l2_int_device_register(&decoder->v4l2_int_device); |
1429 | if (err) { | 1439 | if (err) { |
1430 | i2c_set_clientdata(client, NULL); | 1440 | i2c_set_clientdata(client, NULL); |
1431 | v4l_err(client, | 1441 | v4l_err(client, |
1432 | "Unable to register to v4l2. Err[%d]\n", err); | 1442 | "Unable to register to v4l2. Err[%d]\n", err); |
1443 | goto out_free; | ||
1433 | 1444 | ||
1434 | } else | 1445 | } else |
1435 | v4l_info(client, "Registered to v4l2 master %s!!\n", | 1446 | v4l_info(client, "Registered to v4l2 master %s!!\n", |
1436 | decoder->pdata->master); | 1447 | decoder->pdata->master); |
1437 | |||
1438 | return 0; | 1448 | return 0; |
1449 | |||
1450 | out_free: | ||
1451 | kfree(decoder); | ||
1452 | return err; | ||
1439 | } | 1453 | } |
1440 | 1454 | ||
1441 | /** | 1455 | /** |
@@ -1452,9 +1466,9 @@ static int __exit tvp514x_remove(struct i2c_client *client) | |||
1452 | if (!client->adapter) | 1466 | if (!client->adapter) |
1453 | return -ENODEV; /* our client isn't attached */ | 1467 | return -ENODEV; /* our client isn't attached */ |
1454 | 1468 | ||
1455 | v4l2_int_device_unregister(decoder->v4l2_int_device); | 1469 | v4l2_int_device_unregister(&decoder->v4l2_int_device); |
1456 | i2c_set_clientdata(client, NULL); | 1470 | i2c_set_clientdata(client, NULL); |
1457 | 1471 | kfree(decoder); | |
1458 | return 0; | 1472 | return 0; |
1459 | } | 1473 | } |
1460 | /* | 1474 | /* |