1/* 2 * adv7180.c Analog Devices ADV7180 video decoder driver 3 * Copyright (c) 2009 Intel Corporation 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19#include <linux/module.h> 20#include <linux/init.h> 21#include <linux/errno.h> 22#include <linux/kernel.h> 23#include <linux/interrupt.h> 24#include <linux/i2c.h> 25#include <linux/i2c-id.h> 26#include <linux/slab.h> 27#include <media/v4l2-ioctl.h> 28#include <linux/videodev2.h> 29#include <media/v4l2-device.h> 30#include <media/v4l2-chip-ident.h> 31#include <linux/mutex.h> 32 33#define DRIVER_NAME "adv7180" 34 35#define ADV7180_INPUT_CONTROL_REG 0x00 36#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00 37#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10 38#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM 0x20 39#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM 0x30 40#define ADV7180_INPUT_CONTROL_NTSC_J 0x40 41#define ADV7180_INPUT_CONTROL_NTSC_M 0x50 42#define ADV7180_INPUT_CONTROL_PAL60 0x60 43#define ADV7180_INPUT_CONTROL_NTSC_443 0x70 44#define ADV7180_INPUT_CONTROL_PAL_BG 0x80 45#define ADV7180_INPUT_CONTROL_PAL_N 0x90 46#define ADV7180_INPUT_CONTROL_PAL_M 0xa0 47#define ADV7180_INPUT_CONTROL_PAL_M_PED 0xb0 48#define ADV7180_INPUT_CONTROL_PAL_COMB_N 0xc0 49#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0 50#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0 51#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0 52 53#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04 54#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5 55 56#define ADV7180_AUTODETECT_ENABLE_REG 0x07 57#define ADV7180_AUTODETECT_DEFAULT 0x7f 58 59#define ADV7180_ADI_CTRL_REG 0x0e 60#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20 61 62#define ADV7180_STATUS1_REG 0x10 63#define ADV7180_STATUS1_IN_LOCK 0x01 64#define ADV7180_STATUS1_AUTOD_MASK 0x70 65#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00 66#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10 67#define ADV7180_STATUS1_AUTOD_PAL_M 0x20 68#define ADV7180_STATUS1_AUTOD_PAL_60 0x30 69#define ADV7180_STATUS1_AUTOD_PAL_B_G 0x40 70#define ADV7180_STATUS1_AUTOD_SECAM 0x50 71#define ADV7180_STATUS1_AUTOD_PAL_COMB 0x60 72#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70 73 74#define ADV7180_IDENT_REG 0x11 75#define ADV7180_ID_7180 0x18 76 77#define ADV7180_ICONF1_ADI 0x40 78#define ADV7180_ICONF1_ACTIVE_LOW 0x01 79#define ADV7180_ICONF1_PSYNC_ONLY 0x10 80#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0 81 82#define ADV7180_IRQ1_LOCK 0x01 83#define ADV7180_IRQ1_UNLOCK 0x02 84#define ADV7180_ISR1_ADI 0x42 85#define ADV7180_ICR1_ADI 0x43 86#define ADV7180_IMR1_ADI 0x44 87#define ADV7180_IMR2_ADI 0x48 88#define ADV7180_IRQ3_AD_CHANGE 0x08 89#define ADV7180_ISR3_ADI 0x4A 90#define ADV7180_ICR3_ADI 0x4B 91#define ADV7180_IMR3_ADI 0x4C 92#define ADV7180_IMR4_ADI 0x50 93 94struct adv7180_state { 95 struct v4l2_subdev sd; 96 struct work_struct work; 97 struct mutex mutex; /* mutual excl. when accessing chip */ 98 int irq; 99 v4l2_std_id curr_norm; 100 bool autodetect; 101}; 102 103static v4l2_std_id adv7180_std_to_v4l2(u8 status1) 104{ 105 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) { 106 case ADV7180_STATUS1_AUTOD_NTSM_M_J: 107 return V4L2_STD_NTSC; 108 case ADV7180_STATUS1_AUTOD_NTSC_4_43: 109 return V4L2_STD_NTSC_443; 110 case ADV7180_STATUS1_AUTOD_PAL_M: 111 return V4L2_STD_PAL_M; 112 case ADV7180_STATUS1_AUTOD_PAL_60: 113 return V4L2_STD_PAL_60; 114 case ADV7180_STATUS1_AUTOD_PAL_B_G: 115 return V4L2_STD_PAL; 116 case ADV7180_STATUS1_AUTOD_SECAM: 117 return V4L2_STD_SECAM; 118 case ADV7180_STATUS1_AUTOD_PAL_COMB: 119 return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N; 120 case ADV7180_STATUS1_AUTOD_SECAM_525: 121 return V4L2_STD_SECAM; 122 default: 123 return V4L2_STD_UNKNOWN; 124 } 125} 126 127static int v4l2_std_to_adv7180(v4l2_std_id std) 128{ 129 if (std == V4L2_STD_PAL_60) 130 return ADV7180_INPUT_CONTROL_PAL60; 131 if (std == V4L2_STD_NTSC_443) 132 return ADV7180_INPUT_CONTROL_NTSC_443; 133 if (std == V4L2_STD_PAL_N) 134 return ADV7180_INPUT_CONTROL_PAL_N; 135 if (std == V4L2_STD_PAL_M) 136 return ADV7180_INPUT_CONTROL_PAL_M; 137 if (std == V4L2_STD_PAL_Nc) 138 return ADV7180_INPUT_CONTROL_PAL_COMB_N; 139 140 if (std & V4L2_STD_PAL) 141 return ADV7180_INPUT_CONTROL_PAL_BG; 142 if (std & V4L2_STD_NTSC) 143 return ADV7180_INPUT_CONTROL_NTSC_M; 144 if (std & V4L2_STD_SECAM) 145 return ADV7180_INPUT_CONTROL_PAL_SECAM; 146 147 return -EINVAL; 148} 149 150static u32 adv7180_status_to_v4l2(u8 status1) 151{ 152 if (!(status1 & ADV7180_STATUS1_IN_LOCK)) 153 return V4L2_IN_ST_NO_SIGNAL; 154 155 return 0; 156} 157 158static int __adv7180_status(struct i2c_client *client, u32 *status, 159 v4l2_std_id *std) 160{ 161 int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG); 162 163 if (status1 < 0) 164 return status1; 165 166 if (status) 167 *status = adv7180_status_to_v4l2(status1); 168 if (std) 169 *std = adv7180_std_to_v4l2(status1); 170 171 return 0; 172} 173 174static inline struct adv7180_state *to_state(struct v4l2_subdev *sd) 175{ 176 return container_of(sd, struct adv7180_state, sd); 177} 178 179static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 180{ 181 struct adv7180_state *state = to_state(sd); 182 int err = mutex_lock_interruptible(&state->mutex); 183 if (err) 184 return err; 185 186 /* when we are interrupt driven we know the state */ 187 if (!state->autodetect || state->irq > 0) 188 *std = state->curr_norm; 189 else 190 err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std); 191 192 mutex_unlock(&state->mutex); 193 return err; 194} 195 196static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status) 197{ 198 struct adv7180_state *state = to_state(sd); 199 int ret = mutex_lock_interruptible(&state->mutex); 200 if (ret) 201 return ret; 202 203 ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL); 204 mutex_unlock(&state->mutex); 205 return ret; 206} 207 208static int adv7180_g_chip_ident(struct v4l2_subdev *sd, 209 struct v4l2_dbg_chip_ident *chip) 210{ 211 struct i2c_client *client = v4l2_get_subdevdata(sd); 212 213 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0); 214} 215 216static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 217{ 218 struct adv7180_state *state = to_state(sd); 219 struct i2c_client *client = v4l2_get_subdevdata(sd); 220 int ret = mutex_lock_interruptible(&state->mutex); 221 if (ret) 222 return ret; 223 224 /* all standards -> autodetect */ 225 if (std == V4L2_STD_ALL) { 226 ret = i2c_smbus_write_byte_data(client, 227 ADV7180_INPUT_CONTROL_REG, 228 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM); 229 if (ret < 0) 230 goto out; 231 232 __adv7180_status(client, NULL, &state->curr_norm); 233 state->autodetect = true; 234 } else { 235 ret = v4l2_std_to_adv7180(std); 236 if (ret < 0) 237 goto out; 238 239 ret = i2c_smbus_write_byte_data(client, 240 ADV7180_INPUT_CONTROL_REG, ret); 241 if (ret < 0) 242 goto out; 243 244 state->curr_norm = std; 245 state->autodetect = false; 246 } 247 ret = 0; 248out: 249 mutex_unlock(&state->mutex); 250 return ret; 251} 252 253static const struct v4l2_subdev_video_ops adv7180_video_ops = { 254 .querystd = adv7180_querystd, 255 .g_input_status = adv7180_g_input_status, 256}; 257 258static const struct v4l2_subdev_core_ops adv7180_core_ops = { 259 .g_chip_ident = adv7180_g_chip_ident, 260 .s_std = adv7180_s_std, 261}; 262 263static const struct v4l2_subdev_ops adv7180_ops = { 264 .core = &adv7180_core_ops, 265 .video = &adv7180_video_ops, 266}; 267 268static void adv7180_work(struct work_struct *work) 269{ 270 struct adv7180_state *state = container_of(work, struct adv7180_state, 271 work); 272 struct i2c_client *client = v4l2_get_subdevdata(&state->sd); 273 u8 isr3; 274 275 mutex_lock(&state->mutex); 276 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 277 ADV7180_ADI_CTRL_IRQ_SPACE); 278 isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI); 279 /* clear */ 280 i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3); 281 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0); 282 283 if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect) 284 __adv7180_status(client, NULL, &state->curr_norm); 285 mutex_unlock(&state->mutex); 286 287 enable_irq(state->irq); 288} 289 290static irqreturn_t adv7180_irq(int irq, void *devid) 291{ 292 struct adv7180_state *state = devid; 293 294 schedule_work(&state->work); 295 296 disable_irq_nosync(state->irq); 297 298 return IRQ_HANDLED; 299} 300 301/* 302 * Generic i2c probe 303 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 304 */ 305 306static __devinit int adv7180_probe(struct i2c_client *client, 307 const struct i2c_device_id *id) 308{ 309 struct adv7180_state *state; 310 struct v4l2_subdev *sd; 311 int ret; 312 313 /* Check if the adapter supports the needed features */ 314 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 315 return -EIO; 316 317 v4l_info(client, "chip found @ 0x%02x (%s)\n", 318 client->addr << 1, client->adapter->name); 319 320 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL); 321 if (state == NULL) { 322 ret = -ENOMEM; 323 goto err; 324 } 325 326 state->irq = client->irq; 327 INIT_WORK(&state->work, adv7180_work); 328 mutex_init(&state->mutex); 329 state->autodetect = true; 330 sd = &state->sd; 331 v4l2_i2c_subdev_init(sd, client, &adv7180_ops); 332 333 /* Initialize adv7180 */ 334 /* Enable autodetection */ 335 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG, 336 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM); 337 if (ret < 0) 338 goto err_unreg_subdev; 339 340 ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG, 341 ADV7180_AUTODETECT_DEFAULT); 342 if (ret < 0) 343 goto err_unreg_subdev; 344 345 /* ITU-R BT.656-4 compatible */ 346 ret = i2c_smbus_write_byte_data(client, 347 ADV7180_EXTENDED_OUTPUT_CONTROL_REG, 348 ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS); 349 if (ret < 0) 350 goto err_unreg_subdev; 351 352 /* read current norm */ 353 __adv7180_status(client, NULL, &state->curr_norm); 354 355 /* register for interrupts */ 356 if (state->irq > 0) { 357 ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME, 358 state); 359 if (ret) 360 goto err_unreg_subdev; 361 362 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 363 ADV7180_ADI_CTRL_IRQ_SPACE); 364 if (ret < 0) 365 goto err_unreg_subdev; 366 367 /* config the Interrupt pin to be active low */ 368 ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI, 369 ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY); 370 if (ret < 0) 371 goto err_unreg_subdev; 372 373 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0); 374 if (ret < 0) 375 goto err_unreg_subdev; 376 377 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0); 378 if (ret < 0) 379 goto err_unreg_subdev; 380 381 /* enable AD change interrupts interrupts */ 382 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI, 383 ADV7180_IRQ3_AD_CHANGE); 384 if (ret < 0) 385 goto err_unreg_subdev; 386 387 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0); 388 if (ret < 0) 389 goto err_unreg_subdev; 390 391 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 392 0); 393 if (ret < 0) 394 goto err_unreg_subdev; 395 } 396 397 return 0; 398 399err_unreg_subdev: 400 mutex_destroy(&state->mutex); 401 v4l2_device_unregister_subdev(sd); 402 kfree(state); 403err: 404 printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret); 405 return ret; 406} 407 408static __devexit int adv7180_remove(struct i2c_client *client) 409{ 410 struct v4l2_subdev *sd = i2c_get_clientdata(client); 411 struct adv7180_state *state = to_state(sd); 412 413 if (state->irq > 0) { 414 free_irq(client->irq, state); 415 if (cancel_work_sync(&state->work)) { 416 /* 417 * Work was pending, therefore we need to enable 418 * IRQ here to balance the disable_irq() done in the 419 * interrupt handler. 420 */ 421 enable_irq(state->irq); 422 } 423 } 424 425 mutex_destroy(&state->mutex); 426 v4l2_device_unregister_subdev(sd); 427 kfree(to_state(sd)); 428 return 0; 429} 430 431static const struct i2c_device_id adv7180_id[] = { 432 {DRIVER_NAME, 0}, 433 {}, 434}; 435 436MODULE_DEVICE_TABLE(i2c, adv7180_id); 437 438static struct i2c_driver adv7180_driver = { 439 .driver = { 440 .owner = THIS_MODULE, 441 .name = DRIVER_NAME, 442 }, 443 .probe = adv7180_probe, 444 .remove = __devexit_p(adv7180_remove), 445 .id_table = adv7180_id, 446}; 447 448static __init int adv7180_init(void) 449{ 450 return i2c_add_driver(&adv7180_driver); 451} 452 453static __exit void adv7180_exit(void) 454{ 455 i2c_del_driver(&adv7180_driver); 456} 457 458module_init(adv7180_init); 459module_exit(adv7180_exit); 460 461MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver"); 462MODULE_AUTHOR("Mocean Laboratories"); 463MODULE_LICENSE("GPL v2"); 464