1 /* 2 * ths7303/53- THS7303/53 Video Amplifier driver 3 * 4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 5 * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. 6 * 7 * Author: Chaithrika U S <chaithrika@ti.com> 8 * 9 * Contributors: 10 * Hans Verkuil <hans.verkuil@cisco.com> 11 * Lad, Prabhakar <prabhakar.lad@ti.com> 12 * Martin Bugge <marbugge@cisco.com> 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License as 16 * published by the Free Software Foundation version 2. 17 * 18 * This program is distributed .as is. WITHOUT ANY WARRANTY of any 19 * kind, whether express or implied; without even the implied warranty 20 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 */ 23 24 #include <linux/i2c.h> 25 #include <linux/module.h> 26 #include <linux/slab.h> 27 28 #include <media/ths7303.h> 29 #include <media/v4l2-chip-ident.h> 30 #include <media/v4l2-device.h> 31 32 #define THS7303_CHANNEL_1 1 33 #define THS7303_CHANNEL_2 2 34 #define THS7303_CHANNEL_3 3 35 36 struct ths7303_state { 37 struct v4l2_subdev sd; 38 struct ths7303_platform_data pdata; 39 struct v4l2_bt_timings bt; 40 int std_id; 41 int stream_on; 42 int driver_data; 43 }; 44 45 enum ths7303_filter_mode { 46 THS7303_FILTER_MODE_480I_576I, 47 THS7303_FILTER_MODE_480P_576P, 48 THS7303_FILTER_MODE_720P_1080I, 49 THS7303_FILTER_MODE_1080P, 50 THS7303_FILTER_MODE_DISABLE 51 }; 52 53 MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); 54 MODULE_AUTHOR("Chaithrika U S"); 55 MODULE_LICENSE("GPL"); 56 57 static int debug; 58 module_param(debug, int, 0644); 59 MODULE_PARM_DESC(debug, "Debug level 0-1"); 60 61 static inline struct ths7303_state *to_state(struct v4l2_subdev *sd) 62 { 63 return container_of(sd, struct ths7303_state, sd); 64 } 65 66 static int ths7303_read(struct v4l2_subdev *sd, u8 reg) 67 { 68 struct i2c_client *client = v4l2_get_subdevdata(sd); 69 70 return i2c_smbus_read_byte_data(client, reg); 71 } 72 73 static int ths7303_write(struct v4l2_subdev *sd, u8 reg, u8 val) 74 { 75 struct i2c_client *client = v4l2_get_subdevdata(sd); 76 int ret; 77 int i; 78 79 for (i = 0; i < 3; i++) { 80 ret = i2c_smbus_write_byte_data(client, reg, val); 81 if (ret == 0) 82 return 0; 83 } 84 return ret; 85 } 86 87 /* following function is used to set ths7303 */ 88 int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode) 89 { 90 struct i2c_client *client = v4l2_get_subdevdata(sd); 91 struct ths7303_state *state = to_state(sd); 92 struct ths7303_platform_data *pdata = &state->pdata; 93 u8 val, sel = 0; 94 int err, disable = 0; 95 96 if (!client) 97 return -EINVAL; 98 99 switch (mode) { 100 case THS7303_FILTER_MODE_1080P: 101 sel = 0x3; /*1080p and SXGA/UXGA */ 102 break; 103 case THS7303_FILTER_MODE_720P_1080I: 104 sel = 0x2; /*720p, 1080i and SVGA/XGA */ 105 break; 106 case THS7303_FILTER_MODE_480P_576P: 107 sel = 0x1; /* EDTV 480p/576p and VGA */ 108 break; 109 case THS7303_FILTER_MODE_480I_576I: 110 sel = 0x0; /* SDTV, S-Video, 480i/576i */ 111 break; 112 default: 113 /* disable all channels */ 114 disable = 1; 115 } 116 117 val = (sel << 6) | (sel << 3); 118 if (!disable) 119 val |= (pdata->ch_1 & 0x27); 120 err = ths7303_write(sd, THS7303_CHANNEL_1, val); 121 if (err) 122 goto out; 123 124 val = (sel << 6) | (sel << 3); 125 if (!disable) 126 val |= (pdata->ch_2 & 0x27); 127 err = ths7303_write(sd, THS7303_CHANNEL_2, val); 128 if (err) 129 goto out; 130 131 val = (sel << 6) | (sel << 3); 132 if (!disable) 133 val |= (pdata->ch_3 & 0x27); 134 err = ths7303_write(sd, THS7303_CHANNEL_3, val); 135 if (err) 136 goto out; 137 138 return 0; 139 out: 140 pr_info("write byte data failed\n"); 141 return err; 142 } 143 144 static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) 145 { 146 struct ths7303_state *state = to_state(sd); 147 148 if (norm & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) { 149 state->std_id = 1; 150 state->bt.pixelclock = 0; 151 return ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I); 152 } 153 154 return ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE); 155 } 156 157 static int ths7303_config(struct v4l2_subdev *sd) 158 { 159 struct ths7303_state *state = to_state(sd); 160 int res; 161 162 if (!state->stream_on) { 163 ths7303_write(sd, THS7303_CHANNEL_1, 164 (ths7303_read(sd, THS7303_CHANNEL_1) & 0xf8) | 165 0x00); 166 ths7303_write(sd, THS7303_CHANNEL_2, 167 (ths7303_read(sd, THS7303_CHANNEL_2) & 0xf8) | 168 0x00); 169 ths7303_write(sd, THS7303_CHANNEL_3, 170 (ths7303_read(sd, THS7303_CHANNEL_3) & 0xf8) | 171 0x00); 172 return 0; 173 } 174 175 if (state->bt.pixelclock > 120000000) 176 res = ths7303_setval(sd, THS7303_FILTER_MODE_1080P); 177 else if (state->bt.pixelclock > 70000000) 178 res = ths7303_setval(sd, THS7303_FILTER_MODE_720P_1080I); 179 else if (state->bt.pixelclock > 20000000) 180 res = ths7303_setval(sd, THS7303_FILTER_MODE_480P_576P); 181 else if (state->std_id) 182 res = ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I); 183 else 184 /* disable all channels */ 185 res = ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE); 186 187 return res; 188 189 } 190 191 static int ths7303_s_stream(struct v4l2_subdev *sd, int enable) 192 { 193 struct ths7303_state *state = to_state(sd); 194 195 state->stream_on = enable; 196 197 return ths7303_config(sd); 198 } 199 200 /* for setting filter for HD output */ 201 static int ths7303_s_dv_timings(struct v4l2_subdev *sd, 202 struct v4l2_dv_timings *dv_timings) 203 { 204 struct ths7303_state *state = to_state(sd); 205 206 if (!dv_timings || dv_timings->type != V4L2_DV_BT_656_1120) 207 return -EINVAL; 208 209 state->bt = dv_timings->bt; 210 state->std_id = 0; 211 212 return ths7303_config(sd); 213 } 214 215 static int ths7303_g_chip_ident(struct v4l2_subdev *sd, 216 struct v4l2_dbg_chip_ident *chip) 217 { 218 struct i2c_client *client = v4l2_get_subdevdata(sd); 219 struct ths7303_state *state = to_state(sd); 220 221 return v4l2_chip_ident_i2c_client(client, chip, state->driver_data, 0); 222 } 223 224 static const struct v4l2_subdev_video_ops ths7303_video_ops = { 225 .s_stream = ths7303_s_stream, 226 .s_std_output = ths7303_s_std_output, 227 .s_dv_timings = ths7303_s_dv_timings, 228 }; 229 230 #ifdef CONFIG_VIDEO_ADV_DEBUG 231 232 static int ths7303_g_register(struct v4l2_subdev *sd, 233 struct v4l2_dbg_register *reg) 234 { 235 struct i2c_client *client = v4l2_get_subdevdata(sd); 236 237 if (!v4l2_chip_match_i2c_client(client, ®->match)) 238 return -EINVAL; 239 if (!capable(CAP_SYS_ADMIN)) 240 return -EPERM; 241 242 reg->size = 1; 243 reg->val = ths7303_read(sd, reg->reg); 244 return 0; 245 } 246 247 static int ths7303_s_register(struct v4l2_subdev *sd, 248 const struct v4l2_dbg_register *reg) 249 { 250 struct i2c_client *client = v4l2_get_subdevdata(sd); 251 252 if (!v4l2_chip_match_i2c_client(client, ®->match)) 253 return -EINVAL; 254 if (!capable(CAP_SYS_ADMIN)) 255 return -EPERM; 256 257 ths7303_write(sd, reg->reg, reg->val); 258 return 0; 259 } 260 #endif 261 262 static const char * const stc_lpf_sel_txt[4] = { 263 "500-kHz Filter", 264 "2.5-MHz Filter", 265 "5-MHz Filter", 266 "5-MHz Filter", 267 }; 268 269 static const char * const in_mux_sel_txt[2] = { 270 "Input A Select", 271 "Input B Select", 272 }; 273 274 static const char * const lpf_freq_sel_txt[4] = { 275 "9-MHz LPF", 276 "16-MHz LPF", 277 "35-MHz LPF", 278 "Bypass LPF", 279 }; 280 281 static const char * const in_bias_sel_dis_cont_txt[8] = { 282 "Disable Channel", 283 "Mute Function - No Output", 284 "DC Bias Select", 285 "DC Bias + 250 mV Offset Select", 286 "AC Bias Select", 287 "Sync Tip Clamp with low bias", 288 "Sync Tip Clamp with mid bias", 289 "Sync Tip Clamp with high bias", 290 }; 291 292 static void ths7303_log_channel_status(struct v4l2_subdev *sd, u8 reg) 293 { 294 u8 val = ths7303_read(sd, reg); 295 296 if ((val & 0x7) == 0) { 297 v4l2_info(sd, "Channel %d Off\n", reg); 298 return; 299 } 300 301 v4l2_info(sd, "Channel %d On\n", reg); 302 v4l2_info(sd, " value 0x%x\n", val); 303 v4l2_info(sd, " %s\n", stc_lpf_sel_txt[(val >> 6) & 0x3]); 304 v4l2_info(sd, " %s\n", in_mux_sel_txt[(val >> 5) & 0x1]); 305 v4l2_info(sd, " %s\n", lpf_freq_sel_txt[(val >> 3) & 0x3]); 306 v4l2_info(sd, " %s\n", in_bias_sel_dis_cont_txt[(val >> 0) & 0x7]); 307 } 308 309 static int ths7303_log_status(struct v4l2_subdev *sd) 310 { 311 struct ths7303_state *state = to_state(sd); 312 313 v4l2_info(sd, "stream %s\n", state->stream_on ? "On" : "Off"); 314 315 if (state->bt.pixelclock) { 316 struct v4l2_bt_timings *bt = bt = &state->bt; 317 u32 frame_width, frame_height; 318 319 frame_width = bt->width + bt->hfrontporch + 320 bt->hsync + bt->hbackporch; 321 frame_height = bt->height + bt->vfrontporch + 322 bt->vsync + bt->vbackporch; 323 v4l2_info(sd, 324 "timings: %dx%d%s%d (%dx%d). Pix freq. = %d Hz. Polarities = 0x%x\n", 325 bt->width, bt->height, bt->interlaced ? "i" : "p", 326 (frame_height * frame_width) > 0 ? 327 (int)bt->pixelclock / 328 (frame_height * frame_width) : 0, 329 frame_width, frame_height, 330 (int)bt->pixelclock, bt->polarities); 331 } else { 332 v4l2_info(sd, "no timings set\n"); 333 } 334 335 ths7303_log_channel_status(sd, THS7303_CHANNEL_1); 336 ths7303_log_channel_status(sd, THS7303_CHANNEL_2); 337 ths7303_log_channel_status(sd, THS7303_CHANNEL_3); 338 339 return 0; 340 } 341 342 static const struct v4l2_subdev_core_ops ths7303_core_ops = { 343 .g_chip_ident = ths7303_g_chip_ident, 344 .log_status = ths7303_log_status, 345 #ifdef CONFIG_VIDEO_ADV_DEBUG 346 .g_register = ths7303_g_register, 347 .s_register = ths7303_s_register, 348 #endif 349 }; 350 351 static const struct v4l2_subdev_ops ths7303_ops = { 352 .core = &ths7303_core_ops, 353 .video = &ths7303_video_ops, 354 }; 355 356 static int ths7303_setup(struct v4l2_subdev *sd) 357 { 358 struct ths7303_state *state = to_state(sd); 359 struct ths7303_platform_data *pdata = &state->pdata; 360 int ret; 361 u8 mask; 362 363 state->stream_on = pdata->init_enable; 364 365 mask = state->stream_on ? 0xff : 0xf8; 366 367 ret = ths7303_write(sd, THS7303_CHANNEL_1, pdata->ch_1 & mask); 368 if (ret) 369 return ret; 370 371 ret = ths7303_write(sd, THS7303_CHANNEL_2, pdata->ch_2 & mask); 372 if (ret) 373 return ret; 374 375 ret = ths7303_write(sd, THS7303_CHANNEL_3, pdata->ch_3 & mask); 376 if (ret) 377 return ret; 378 379 return 0; 380 } 381 382 static int ths7303_probe(struct i2c_client *client, 383 const struct i2c_device_id *id) 384 { 385 struct ths7303_platform_data *pdata = client->dev.platform_data; 386 struct ths7303_state *state; 387 struct v4l2_subdev *sd; 388 389 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 390 return -ENODEV; 391 392 v4l_info(client, "chip found @ 0x%x (%s)\n", 393 client->addr << 1, client->adapter->name); 394 395 state = devm_kzalloc(&client->dev, sizeof(struct ths7303_state), 396 GFP_KERNEL); 397 if (!state) 398 return -ENOMEM; 399 400 if (!pdata) 401 v4l_warn(client, "No platform data, using default data!\n"); 402 else 403 state->pdata = *pdata; 404 405 sd = &state->sd; 406 v4l2_i2c_subdev_init(sd, client, &ths7303_ops); 407 408 /* store the driver data to differntiate the chip */ 409 state->driver_data = (int)id->driver_data; 410 411 if (ths7303_setup(sd) < 0) { 412 v4l_err(client, "init failed\n"); 413 return -EIO; 414 } 415 416 return 0; 417 } 418 419 static int ths7303_remove(struct i2c_client *client) 420 { 421 struct v4l2_subdev *sd = i2c_get_clientdata(client); 422 423 v4l2_device_unregister_subdev(sd); 424 425 return 0; 426 } 427 428 static const struct i2c_device_id ths7303_id[] = { 429 {"ths7303", V4L2_IDENT_THS7303}, 430 {"ths7353", V4L2_IDENT_THS7353}, 431 {}, 432 }; 433 434 MODULE_DEVICE_TABLE(i2c, ths7303_id); 435 436 static struct i2c_driver ths7303_driver = { 437 .driver = { 438 .owner = THIS_MODULE, 439 .name = "ths73x3", 440 }, 441 .probe = ths7303_probe, 442 .remove = ths7303_remove, 443 .id_table = ths7303_id, 444 }; 445 446 module_i2c_driver(ths7303_driver); 447