0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/init.h>
0008 #include <linux/i2c.h>
0009 #include <linux/videodev2.h>
0010 #include <linux/ioctl.h>
0011 #include <linux/slab.h>
0012 #include <media/v4l2-device.h>
0013 #include <media/v4l2-ctrls.h>
0014
0015 MODULE_DESCRIPTION("TW9906 I2C subdev driver");
0016 MODULE_LICENSE("GPL v2");
0017
0018 struct tw9906 {
0019 struct v4l2_subdev sd;
0020 struct v4l2_ctrl_handler hdl;
0021 v4l2_std_id norm;
0022 };
0023
0024 static inline struct tw9906 *to_state(struct v4l2_subdev *sd)
0025 {
0026 return container_of(sd, struct tw9906, sd);
0027 }
0028
0029 static const u8 initial_registers[] = {
0030 0x02, 0x40,
0031 0x03, 0xa2,
0032 0x05, 0x81,
0033 0x07, 0x02,
0034 0x08, 0x14,
0035 0x09, 0xf0,
0036 0x0a, 0x10,
0037 0x0b, 0xd0,
0038 0x0d, 0x00,
0039 0x0e, 0x11,
0040 0x0f, 0x00,
0041 0x10, 0x00,
0042 0x11, 0x60,
0043 0x12, 0x11,
0044 0x13, 0x7e,
0045 0x14, 0x7e,
0046 0x15, 0x00,
0047 0x19, 0x57,
0048 0x1a, 0x0f,
0049 0x1b, 0x40,
0050 0x29, 0x03,
0051 0x55, 0x00,
0052 0x6b, 0x26,
0053 0x6c, 0x36,
0054 0x6d, 0xf0,
0055 0x6e, 0x41,
0056 0x6f, 0x13,
0057 0xad, 0x70,
0058 0x00, 0x00,
0059 };
0060
0061 static int write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
0062 {
0063 struct i2c_client *client = v4l2_get_subdevdata(sd);
0064
0065 return i2c_smbus_write_byte_data(client, reg, value);
0066 }
0067
0068 static int write_regs(struct v4l2_subdev *sd, const u8 *regs)
0069 {
0070 int i;
0071
0072 for (i = 0; regs[i] != 0x00; i += 2)
0073 if (write_reg(sd, regs[i], regs[i + 1]) < 0)
0074 return -1;
0075 return 0;
0076 }
0077
0078 static int tw9906_s_video_routing(struct v4l2_subdev *sd, u32 input,
0079 u32 output, u32 config)
0080 {
0081 write_reg(sd, 0x02, 0x40 | (input << 1));
0082 return 0;
0083 }
0084
0085 static int tw9906_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
0086 {
0087 struct tw9906 *dec = to_state(sd);
0088 bool is_60hz = norm & V4L2_STD_525_60;
0089 static const u8 config_60hz[] = {
0090 0x05, 0x81,
0091 0x07, 0x02,
0092 0x08, 0x14,
0093 0x09, 0xf0,
0094 0, 0,
0095 };
0096 static const u8 config_50hz[] = {
0097 0x05, 0x01,
0098 0x07, 0x12,
0099 0x08, 0x18,
0100 0x09, 0x20,
0101 0, 0,
0102 };
0103
0104 write_regs(sd, is_60hz ? config_60hz : config_50hz);
0105 dec->norm = norm;
0106 return 0;
0107 }
0108
0109 static int tw9906_s_ctrl(struct v4l2_ctrl *ctrl)
0110 {
0111 struct tw9906 *dec = container_of(ctrl->handler, struct tw9906, hdl);
0112 struct v4l2_subdev *sd = &dec->sd;
0113
0114 switch (ctrl->id) {
0115 case V4L2_CID_BRIGHTNESS:
0116 write_reg(sd, 0x10, ctrl->val);
0117 break;
0118 case V4L2_CID_CONTRAST:
0119 write_reg(sd, 0x11, ctrl->val);
0120 break;
0121 case V4L2_CID_HUE:
0122 write_reg(sd, 0x15, ctrl->val);
0123 break;
0124 default:
0125 return -EINVAL;
0126 }
0127 return 0;
0128 }
0129
0130 static int tw9906_log_status(struct v4l2_subdev *sd)
0131 {
0132 struct tw9906 *dec = to_state(sd);
0133 bool is_60hz = dec->norm & V4L2_STD_525_60;
0134
0135 v4l2_info(sd, "Standard: %d Hz\n", is_60hz ? 60 : 50);
0136 v4l2_ctrl_subdev_log_status(sd);
0137 return 0;
0138 }
0139
0140
0141
0142 static const struct v4l2_ctrl_ops tw9906_ctrl_ops = {
0143 .s_ctrl = tw9906_s_ctrl,
0144 };
0145
0146 static const struct v4l2_subdev_core_ops tw9906_core_ops = {
0147 .log_status = tw9906_log_status,
0148 };
0149
0150 static const struct v4l2_subdev_video_ops tw9906_video_ops = {
0151 .s_std = tw9906_s_std,
0152 .s_routing = tw9906_s_video_routing,
0153 };
0154
0155 static const struct v4l2_subdev_ops tw9906_ops = {
0156 .core = &tw9906_core_ops,
0157 .video = &tw9906_video_ops,
0158 };
0159
0160 static int tw9906_probe(struct i2c_client *client,
0161 const struct i2c_device_id *id)
0162 {
0163 struct tw9906 *dec;
0164 struct v4l2_subdev *sd;
0165 struct v4l2_ctrl_handler *hdl;
0166
0167
0168 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
0169 return -EIO;
0170
0171 v4l_info(client, "chip found @ 0x%02x (%s)\n",
0172 client->addr << 1, client->adapter->name);
0173
0174 dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
0175 if (dec == NULL)
0176 return -ENOMEM;
0177 sd = &dec->sd;
0178 v4l2_i2c_subdev_init(sd, client, &tw9906_ops);
0179 hdl = &dec->hdl;
0180 v4l2_ctrl_handler_init(hdl, 4);
0181 v4l2_ctrl_new_std(hdl, &tw9906_ctrl_ops,
0182 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
0183 v4l2_ctrl_new_std(hdl, &tw9906_ctrl_ops,
0184 V4L2_CID_CONTRAST, 0, 255, 1, 0x60);
0185 v4l2_ctrl_new_std(hdl, &tw9906_ctrl_ops,
0186 V4L2_CID_HUE, -128, 127, 1, 0);
0187 sd->ctrl_handler = hdl;
0188 if (hdl->error) {
0189 int err = hdl->error;
0190
0191 v4l2_ctrl_handler_free(hdl);
0192 return err;
0193 }
0194
0195
0196 dec->norm = V4L2_STD_NTSC;
0197
0198 if (write_regs(sd, initial_registers) < 0) {
0199 v4l2_err(client, "error initializing TW9906\n");
0200 return -EINVAL;
0201 }
0202
0203 return 0;
0204 }
0205
0206 static int tw9906_remove(struct i2c_client *client)
0207 {
0208 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0209
0210 v4l2_device_unregister_subdev(sd);
0211 v4l2_ctrl_handler_free(&to_state(sd)->hdl);
0212 return 0;
0213 }
0214
0215
0216
0217 static const struct i2c_device_id tw9906_id[] = {
0218 { "tw9906", 0 },
0219 { }
0220 };
0221 MODULE_DEVICE_TABLE(i2c, tw9906_id);
0222
0223 static struct i2c_driver tw9906_driver = {
0224 .driver = {
0225 .name = "tw9906",
0226 },
0227 .probe = tw9906_probe,
0228 .remove = tw9906_remove,
0229 .id_table = tw9906_id,
0230 };
0231 module_i2c_driver(tw9906_driver);