diff options
Diffstat (limited to 'drivers/media/video/tvp514x.c')
| -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 | /* |
