From: Manjunath Hadli <[email protected]>

The patch adds support for THS7353 video amplifier. Enable
dv_preset support for THS7353 so that setting a HD mode on the
host device makes sure appropriate mode in the amplifier is enabled.

Signed-off-by: Manjunath Hadli <[email protected]>
Signed-off-by: Lad, Prabhakar <[email protected]>
---
 drivers/media/i2c/Kconfig   |   10 ++
 drivers/media/i2c/Makefile  |    1 +
 drivers/media/i2c/ths7353.c |  223 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/i2c/ths7353.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 24d78e2..d1ebb0b 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -570,6 +570,16 @@ config VIDEO_THS7303
          To compile this driver as a module, choose M here: the
          module will be called ths7303.
 
+config VIDEO_THS7353
+       tristate "THS7353 Video Amplifier"
+       depends on I2C
+       help
+         Support for TI THS7353 video amplifier
+
+         To compile this driver as a module, choose M here: the
+         module will be called ths7353. This helps tvp7002 to amplify
+         the signals.
+
 config VIDEO_M52790
        tristate "Mitsubishi M52790 A/V switch"
        depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index b1d62df..9944d06 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_VIDEO_BT856) += bt856.o
 obj-$(CONFIG_VIDEO_BT866) += bt866.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
 obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
+obj-$(CONFIG_VIDEO_THS7353) += ths7353.o
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
 obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
diff --git a/drivers/media/i2c/ths7353.c b/drivers/media/i2c/ths7353.c
new file mode 100644
index 0000000..288cd1f
--- /dev/null
+++ b/drivers/media/i2c/ths7353.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-device.h>
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+#define THS7353_CHANNEL_1      1
+#define THS7353_CHANNEL_2      2
+#define THS7353_CHANNEL_3      3
+
+#define THS7353_DEF_LUMA_CHANNEL       2
+
+/* all supported modes */
+enum ths7353_filter_mode {
+       THS_FILTER_MODE_480I_576I,
+       THS_FILTER_MODE_480P_576P,
+       THS_FILTER_MODE_720P_1080I,
+       THS_FILTER_MODE_1080P
+};
+
+static int ths7353_luma_channel;
+
+/* following function is used to set ths7353 */
+static int ths7353_setvalue(struct v4l2_subdev *sd,
+                           enum ths7353_filter_mode mode)
+{
+       u8 val = 0, input_bias_luma = 5, input_bias_chroma = 4, temp;
+       struct i2c_client *client;
+       int err, disable;
+       int channel = 3;
+
+       client = v4l2_get_subdevdata(sd);
+
+       switch (mode) {
+       case THS_FILTER_MODE_1080P:
+               /* LPF - 5MHz */
+               val = (3 << 6);
+               /* LPF - bypass */
+               val |= (3 << 3);
+               break;
+       case THS_FILTER_MODE_720P_1080I:
+               /* LPF - 5MHz */
+               val = (2 << 6);
+               /* LPF - 35 MHz */
+               val |= (2 << 3);
+               break;
+       case THS_FILTER_MODE_480P_576P:
+               /* LPF - 2.5MHz */
+               val = (1 << 6);
+               /* LPF - 16 MHz */
+               val |= (1 << 3);
+               break;
+       case THS_FILTER_MODE_480I_576I:
+               /* LPF - 500 KHz, LPF - 9 MHz. Do nothing */
+               break;
+       default:
+               /* disable all channels */
+               disable = 1;
+       }
+
+       channel = ths7353_luma_channel;
+
+       /* Setup channel 2 - Luma - Green */
+       temp = val;
+       if (!disable)
+               val |= input_bias_luma;
+       err = i2c_smbus_write_byte_data(client, channel, val);
+       if (err)
+               goto out;
+
+       /* setup two chroma channels */
+       if (!disable)
+               temp |= input_bias_chroma;
+       channel++;
+       if (channel > THS7353_CHANNEL_3)
+               channel = THS7353_CHANNEL_1;
+       err = i2c_smbus_write_byte_data(client, channel, temp);
+       if (err)
+               goto out;
+
+       channel++;
+       if (channel > THS7353_CHANNEL_3)
+               channel = THS7353_CHANNEL_1;
+       err = i2c_smbus_write_byte_data(client, channel, temp);
+       if (err)
+               goto out;
+
+       return 0;
+
+out:
+       v4l2_err(sd, "ths7353 write failed\n");
+       return err;
+}
+
+static int ths7353_s_preset(struct v4l2_subdev *sd,
+                           struct v4l2_dv_preset *preset)
+{
+       switch (preset->preset) {
+       case V4L2_DV_576P50:
+       case V4L2_DV_480P59_94:
+               return ths7353_setvalue(sd, THS_FILTER_MODE_480P_576P);
+
+       case V4L2_DV_720P50:
+       case V4L2_DV_720P60:
+       case V4L2_DV_1080I60:
+       case V4L2_DV_1080I50:
+               return ths7353_setvalue(sd, THS_FILTER_MODE_720P_1080I);
+
+       case V4L2_DV_1080P60:
+               return ths7353_setvalue(sd, THS_FILTER_MODE_1080P);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ths7353_g_chip_ident(struct v4l2_subdev *sd,
+                               struct v4l2_dbg_chip_ident *chip)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_THS7353, 0);
+}
+
+static const struct v4l2_subdev_video_ops ths7353_video_ops = {
+       .s_dv_preset    = ths7353_s_preset,
+};
+
+static const struct v4l2_subdev_core_ops ths7353_core_ops = {
+       .g_chip_ident   = ths7353_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops ths7353_ops = {
+       .core   = &ths7353_core_ops,
+       .video  = &ths7353_video_ops,
+};
+
+static int ths7353_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       struct v4l2_subdev *sd;
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
+
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                               client->addr << 1, client->adapter->name);
+
+       if (!client->dev.platform_data) {
+               v4l_warn(client, "No platform data!!\n");
+               ths7353_luma_channel = THS7353_DEF_LUMA_CHANNEL;
+       } else {
+               ths7353_luma_channel = (int)(client->dev.platform_data);
+               if (ths7353_luma_channel < THS7353_CHANNEL_1 ||
+                   ths7353_luma_channel > THS7353_CHANNEL_3) {
+                       v4l_warn(client, "Invalid Luma Channel!!\n");
+                       ths7353_luma_channel = THS7353_DEF_LUMA_CHANNEL;
+               }
+       }
+
+       sd = devm_kzalloc(&client->dev, sizeof(struct v4l2_subdev), GFP_KERNEL);
+       if (sd == NULL)
+               return -ENOMEM;
+
+       v4l2_i2c_subdev_init(sd, client, &ths7353_ops);
+       strlcpy(sd->name, "ths7353", sizeof(sd->name));
+
+       return ths7353_setvalue(sd, THS_FILTER_MODE_480I_576I);
+}
+
+static int ths7353_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+       v4l2_device_unregister_subdev(sd);
+
+       return 0;
+}
+
+static const struct i2c_device_id ths7353_id[] = {
+       {"ths7353", 0},
+       {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ths7353_id);
+
+static struct i2c_driver ths7353_driver = {
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "ths7353",
+       },
+       .probe          = ths7353_probe,
+       .remove         = ths7353_remove,
+       .id_table       = ths7353_id,
+};
+
+module_i2c_driver(ths7353_driver);
+
+MODULE_DESCRIPTION("TI THS7353 video amplifier driver");
+MODULE_AUTHOR("Muralidharan Karicheri");
+MODULE_LICENSE("GPL");
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to