linux/drivers/media/i2c/adv7180.c
<<
>>
Prefs
   1/*
   2 * adv7180.c Analog Devices ADV7180 video decoder driver
   3 * Copyright (c) 2009 Intel Corporation
   4 * Copyright (C) 2013 Cogent Embedded, Inc.
   5 * Copyright (C) 2013 Renesas Solutions Corp.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20
  21#include <linux/module.h>
  22#include <linux/init.h>
  23#include <linux/errno.h>
  24#include <linux/kernel.h>
  25#include <linux/interrupt.h>
  26#include <linux/i2c.h>
  27#include <linux/slab.h>
  28#include <media/v4l2-ioctl.h>
  29#include <linux/videodev2.h>
  30#include <media/v4l2-device.h>
  31#include <media/v4l2-ctrls.h>
  32#include <linux/mutex.h>
  33
  34#define ADV7180_INPUT_CONTROL_REG                       0x00
  35#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM    0x00
  36#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
  37#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM     0x20
  38#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM     0x30
  39#define ADV7180_INPUT_CONTROL_NTSC_J                    0x40
  40#define ADV7180_INPUT_CONTROL_NTSC_M                    0x50
  41#define ADV7180_INPUT_CONTROL_PAL60                     0x60
  42#define ADV7180_INPUT_CONTROL_NTSC_443                  0x70
  43#define ADV7180_INPUT_CONTROL_PAL_BG                    0x80
  44#define ADV7180_INPUT_CONTROL_PAL_N                     0x90
  45#define ADV7180_INPUT_CONTROL_PAL_M                     0xa0
  46#define ADV7180_INPUT_CONTROL_PAL_M_PED                 0xb0
  47#define ADV7180_INPUT_CONTROL_PAL_COMB_N                0xc0
  48#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED            0xd0
  49#define ADV7180_INPUT_CONTROL_PAL_SECAM                 0xe0
  50#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED             0xf0
  51#define ADV7180_INPUT_CONTROL_INSEL_MASK                0x0f
  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/* Contrast */
  59#define ADV7180_CON_REG         0x08    /*Unsigned */
  60#define ADV7180_CON_MIN         0
  61#define ADV7180_CON_DEF         128
  62#define ADV7180_CON_MAX         255
  63/* Brightness*/
  64#define ADV7180_BRI_REG         0x0a    /*Signed */
  65#define ADV7180_BRI_MIN         -128
  66#define ADV7180_BRI_DEF         0
  67#define ADV7180_BRI_MAX         127
  68/* Hue */
  69#define ADV7180_HUE_REG         0x0b    /*Signed, inverted */
  70#define ADV7180_HUE_MIN         -127
  71#define ADV7180_HUE_DEF         0
  72#define ADV7180_HUE_MAX         128
  73
  74#define ADV7180_ADI_CTRL_REG                            0x0e
  75#define ADV7180_ADI_CTRL_IRQ_SPACE                      0x20
  76
  77#define ADV7180_PWR_MAN_REG             0x0f
  78#define ADV7180_PWR_MAN_ON              0x04
  79#define ADV7180_PWR_MAN_OFF             0x24
  80#define ADV7180_PWR_MAN_RES             0x80
  81
  82#define ADV7180_STATUS1_REG                             0x10
  83#define ADV7180_STATUS1_IN_LOCK         0x01
  84#define ADV7180_STATUS1_AUTOD_MASK      0x70
  85#define ADV7180_STATUS1_AUTOD_NTSM_M_J  0x00
  86#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
  87#define ADV7180_STATUS1_AUTOD_PAL_M     0x20
  88#define ADV7180_STATUS1_AUTOD_PAL_60    0x30
  89#define ADV7180_STATUS1_AUTOD_PAL_B_G   0x40
  90#define ADV7180_STATUS1_AUTOD_SECAM     0x50
  91#define ADV7180_STATUS1_AUTOD_PAL_COMB  0x60
  92#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70
  93
  94#define ADV7180_IDENT_REG 0x11
  95#define ADV7180_ID_7180 0x18
  96
  97#define ADV7180_ICONF1_ADI              0x40
  98#define ADV7180_ICONF1_ACTIVE_LOW       0x01
  99#define ADV7180_ICONF1_PSYNC_ONLY       0x10
 100#define ADV7180_ICONF1_ACTIVE_TO_CLR    0xC0
 101/* Saturation */
 102#define ADV7180_SD_SAT_CB_REG   0xe3    /*Unsigned */
 103#define ADV7180_SD_SAT_CR_REG   0xe4    /*Unsigned */
 104#define ADV7180_SAT_MIN         0
 105#define ADV7180_SAT_DEF         128
 106#define ADV7180_SAT_MAX         255
 107
 108#define ADV7180_IRQ1_LOCK       0x01
 109#define ADV7180_IRQ1_UNLOCK     0x02
 110#define ADV7180_ISR1_ADI        0x42
 111#define ADV7180_ICR1_ADI        0x43
 112#define ADV7180_IMR1_ADI        0x44
 113#define ADV7180_IMR2_ADI        0x48
 114#define ADV7180_IRQ3_AD_CHANGE  0x08
 115#define ADV7180_ISR3_ADI        0x4A
 116#define ADV7180_ICR3_ADI        0x4B
 117#define ADV7180_IMR3_ADI        0x4C
 118#define ADV7180_IMR4_ADI        0x50
 119
 120#define ADV7180_NTSC_V_BIT_END_REG      0xE6
 121#define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND     0x4F
 122
 123struct adv7180_state {
 124        struct v4l2_ctrl_handler ctrl_hdl;
 125        struct v4l2_subdev      sd;
 126        struct work_struct      work;
 127        struct mutex            mutex; /* mutual excl. when accessing chip */
 128        int                     irq;
 129        v4l2_std_id             curr_norm;
 130        bool                    autodetect;
 131        u8                      input;
 132};
 133#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler,             \
 134                                            struct adv7180_state,       \
 135                                            ctrl_hdl)->sd)
 136
 137static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
 138{
 139        /* in case V4L2_IN_ST_NO_SIGNAL */
 140        if (!(status1 & ADV7180_STATUS1_IN_LOCK))
 141                return V4L2_STD_UNKNOWN;
 142
 143        switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
 144        case ADV7180_STATUS1_AUTOD_NTSM_M_J:
 145                return V4L2_STD_NTSC;
 146        case ADV7180_STATUS1_AUTOD_NTSC_4_43:
 147                return V4L2_STD_NTSC_443;
 148        case ADV7180_STATUS1_AUTOD_PAL_M:
 149                return V4L2_STD_PAL_M;
 150        case ADV7180_STATUS1_AUTOD_PAL_60:
 151                return V4L2_STD_PAL_60;
 152        case ADV7180_STATUS1_AUTOD_PAL_B_G:
 153                return V4L2_STD_PAL;
 154        case ADV7180_STATUS1_AUTOD_SECAM:
 155                return V4L2_STD_SECAM;
 156        case ADV7180_STATUS1_AUTOD_PAL_COMB:
 157                return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
 158        case ADV7180_STATUS1_AUTOD_SECAM_525:
 159                return V4L2_STD_SECAM;
 160        default:
 161                return V4L2_STD_UNKNOWN;
 162        }
 163}
 164
 165static int v4l2_std_to_adv7180(v4l2_std_id std)
 166{
 167        if (std == V4L2_STD_PAL_60)
 168                return ADV7180_INPUT_CONTROL_PAL60;
 169        if (std == V4L2_STD_NTSC_443)
 170                return ADV7180_INPUT_CONTROL_NTSC_443;
 171        if (std == V4L2_STD_PAL_N)
 172                return ADV7180_INPUT_CONTROL_PAL_N;
 173        if (std == V4L2_STD_PAL_M)
 174                return ADV7180_INPUT_CONTROL_PAL_M;
 175        if (std == V4L2_STD_PAL_Nc)
 176                return ADV7180_INPUT_CONTROL_PAL_COMB_N;
 177
 178        if (std & V4L2_STD_PAL)
 179                return ADV7180_INPUT_CONTROL_PAL_BG;
 180        if (std & V4L2_STD_NTSC)
 181                return ADV7180_INPUT_CONTROL_NTSC_M;
 182        if (std & V4L2_STD_SECAM)
 183                return ADV7180_INPUT_CONTROL_PAL_SECAM;
 184
 185        return -EINVAL;
 186}
 187
 188static u32 adv7180_status_to_v4l2(u8 status1)
 189{
 190        if (!(status1 & ADV7180_STATUS1_IN_LOCK))
 191                return V4L2_IN_ST_NO_SIGNAL;
 192
 193        return 0;
 194}
 195
 196static int __adv7180_status(struct i2c_client *client, u32 *status,
 197                            v4l2_std_id *std)
 198{
 199        int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
 200
 201        if (status1 < 0)
 202                return status1;
 203
 204        if (status)
 205                *status = adv7180_status_to_v4l2(status1);
 206        if (std)
 207                *std = adv7180_std_to_v4l2(status1);
 208
 209        return 0;
 210}
 211
 212static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
 213{
 214        return container_of(sd, struct adv7180_state, sd);
 215}
 216
 217static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 218{
 219        struct adv7180_state *state = to_state(sd);
 220        int err = mutex_lock_interruptible(&state->mutex);
 221        if (err)
 222                return err;
 223
 224        /* when we are interrupt driven we know the state */
 225        if (!state->autodetect || state->irq > 0)
 226                *std = state->curr_norm;
 227        else
 228                err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
 229
 230        mutex_unlock(&state->mutex);
 231        return err;
 232}
 233
 234static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input,
 235                             u32 output, u32 config)
 236{
 237        struct adv7180_state *state = to_state(sd);
 238        int ret = mutex_lock_interruptible(&state->mutex);
 239        struct i2c_client *client = v4l2_get_subdevdata(sd);
 240
 241        if (ret)
 242                return ret;
 243
 244        /* We cannot discriminate between LQFP and 40-pin LFCSP, so accept
 245         * all inputs and let the card driver take care of validation
 246         */
 247        if ((input & ADV7180_INPUT_CONTROL_INSEL_MASK) != input)
 248                goto out;
 249
 250        ret = i2c_smbus_read_byte_data(client, ADV7180_INPUT_CONTROL_REG);
 251
 252        if (ret < 0)
 253                goto out;
 254
 255        ret &= ~ADV7180_INPUT_CONTROL_INSEL_MASK;
 256        ret = i2c_smbus_write_byte_data(client,
 257                                        ADV7180_INPUT_CONTROL_REG, ret | input);
 258        state->input = input;
 259out:
 260        mutex_unlock(&state->mutex);
 261        return ret;
 262}
 263
 264static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
 265{
 266        struct adv7180_state *state = to_state(sd);
 267        int ret = mutex_lock_interruptible(&state->mutex);
 268        if (ret)
 269                return ret;
 270
 271        ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL);
 272        mutex_unlock(&state->mutex);
 273        return ret;
 274}
 275
 276static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 277{
 278        struct adv7180_state *state = to_state(sd);
 279        struct i2c_client *client = v4l2_get_subdevdata(sd);
 280        int ret = mutex_lock_interruptible(&state->mutex);
 281        if (ret)
 282                return ret;
 283
 284        /* all standards -> autodetect */
 285        if (std == V4L2_STD_ALL) {
 286                ret =
 287                    i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
 288                                ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
 289                                              | state->input);
 290                if (ret < 0)
 291                        goto out;
 292
 293                __adv7180_status(client, NULL, &state->curr_norm);
 294                state->autodetect = true;
 295        } else {
 296                ret = v4l2_std_to_adv7180(std);
 297                if (ret < 0)
 298                        goto out;
 299
 300                ret = i2c_smbus_write_byte_data(client,
 301                                                ADV7180_INPUT_CONTROL_REG,
 302                                                ret | state->input);
 303                if (ret < 0)
 304                        goto out;
 305
 306                state->curr_norm = std;
 307                state->autodetect = false;
 308        }
 309        ret = 0;
 310out:
 311        mutex_unlock(&state->mutex);
 312        return ret;
 313}
 314
 315static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
 316{
 317        struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
 318        struct adv7180_state *state = to_state(sd);
 319        struct i2c_client *client = v4l2_get_subdevdata(sd);
 320        int ret = mutex_lock_interruptible(&state->mutex);
 321        int val;
 322
 323        if (ret)
 324                return ret;
 325        val = ctrl->val;
 326        switch (ctrl->id) {
 327        case V4L2_CID_BRIGHTNESS:
 328                ret = i2c_smbus_write_byte_data(client, ADV7180_BRI_REG, val);
 329                break;
 330        case V4L2_CID_HUE:
 331                /*Hue is inverted according to HSL chart */
 332                ret = i2c_smbus_write_byte_data(client, ADV7180_HUE_REG, -val);
 333                break;
 334        case V4L2_CID_CONTRAST:
 335                ret = i2c_smbus_write_byte_data(client, ADV7180_CON_REG, val);
 336                break;
 337        case V4L2_CID_SATURATION:
 338                /*
 339                 *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE
 340                 *Let's not confuse the user, everybody understands saturation
 341                 */
 342                ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CB_REG,
 343                                                val);
 344                if (ret < 0)
 345                        break;
 346                ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CR_REG,
 347                                                val);
 348                break;
 349        default:
 350                ret = -EINVAL;
 351        }
 352
 353        mutex_unlock(&state->mutex);
 354        return ret;
 355}
 356
 357static const struct v4l2_ctrl_ops adv7180_ctrl_ops = {
 358        .s_ctrl = adv7180_s_ctrl,
 359};
 360
 361static int adv7180_init_controls(struct adv7180_state *state)
 362{
 363        v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
 364
 365        v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
 366                          V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN,
 367                          ADV7180_BRI_MAX, 1, ADV7180_BRI_DEF);
 368        v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
 369                          V4L2_CID_CONTRAST, ADV7180_CON_MIN,
 370                          ADV7180_CON_MAX, 1, ADV7180_CON_DEF);
 371        v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
 372                          V4L2_CID_SATURATION, ADV7180_SAT_MIN,
 373                          ADV7180_SAT_MAX, 1, ADV7180_SAT_DEF);
 374        v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
 375                          V4L2_CID_HUE, ADV7180_HUE_MIN,
 376                          ADV7180_HUE_MAX, 1, ADV7180_HUE_DEF);
 377        state->sd.ctrl_handler = &state->ctrl_hdl;
 378        if (state->ctrl_hdl.error) {
 379                int err = state->ctrl_hdl.error;
 380
 381                v4l2_ctrl_handler_free(&state->ctrl_hdl);
 382                return err;
 383        }
 384        v4l2_ctrl_handler_setup(&state->ctrl_hdl);
 385
 386        return 0;
 387}
 388static void adv7180_exit_controls(struct adv7180_state *state)
 389{
 390        v4l2_ctrl_handler_free(&state->ctrl_hdl);
 391}
 392
 393static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
 394                                 enum v4l2_mbus_pixelcode *code)
 395{
 396        if (index > 0)
 397                return -EINVAL;
 398
 399        *code = V4L2_MBUS_FMT_YUYV8_2X8;
 400
 401        return 0;
 402}
 403
 404static int adv7180_mbus_fmt(struct v4l2_subdev *sd,
 405                            struct v4l2_mbus_framefmt *fmt)
 406{
 407        struct adv7180_state *state = to_state(sd);
 408
 409        fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
 410        fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
 411        fmt->field = V4L2_FIELD_INTERLACED;
 412        fmt->width = 720;
 413        fmt->height = state->curr_norm & V4L2_STD_525_60 ? 480 : 576;
 414
 415        return 0;
 416}
 417
 418static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
 419                                 struct v4l2_mbus_config *cfg)
 420{
 421        /*
 422         * The ADV7180 sensor supports BT.601/656 output modes.
 423         * The BT.656 is default and not yet configurable by s/w.
 424         */
 425        cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
 426                     V4L2_MBUS_DATA_ACTIVE_HIGH;
 427        cfg->type = V4L2_MBUS_BT656;
 428
 429        return 0;
 430}
 431
 432static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 433        .querystd = adv7180_querystd,
 434        .g_input_status = adv7180_g_input_status,
 435        .s_routing = adv7180_s_routing,
 436        .enum_mbus_fmt = adv7180_enum_mbus_fmt,
 437        .try_mbus_fmt = adv7180_mbus_fmt,
 438        .g_mbus_fmt = adv7180_mbus_fmt,
 439        .s_mbus_fmt = adv7180_mbus_fmt,
 440        .g_mbus_config = adv7180_g_mbus_config,
 441};
 442
 443static const struct v4l2_subdev_core_ops adv7180_core_ops = {
 444        .s_std = adv7180_s_std,
 445};
 446
 447static const struct v4l2_subdev_ops adv7180_ops = {
 448        .core = &adv7180_core_ops,
 449        .video = &adv7180_video_ops,
 450};
 451
 452static void adv7180_work(struct work_struct *work)
 453{
 454        struct adv7180_state *state = container_of(work, struct adv7180_state,
 455                                                   work);
 456        struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
 457        u8 isr3;
 458
 459        mutex_lock(&state->mutex);
 460        i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
 461                                  ADV7180_ADI_CTRL_IRQ_SPACE);
 462        isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
 463        /* clear */
 464        i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
 465        i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0);
 466
 467        if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
 468                __adv7180_status(client, NULL, &state->curr_norm);
 469        mutex_unlock(&state->mutex);
 470
 471        enable_irq(state->irq);
 472}
 473
 474static irqreturn_t adv7180_irq(int irq, void *devid)
 475{
 476        struct adv7180_state *state = devid;
 477
 478        schedule_work(&state->work);
 479
 480        disable_irq_nosync(state->irq);
 481
 482        return IRQ_HANDLED;
 483}
 484
 485static int init_device(struct i2c_client *client, struct adv7180_state *state)
 486{
 487        int ret;
 488
 489        /* Initialize adv7180 */
 490        /* Enable autodetection */
 491        if (state->autodetect) {
 492                ret =
 493                    i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
 494                                ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
 495                                              | state->input);
 496                if (ret < 0)
 497                        return ret;
 498
 499                ret =
 500                    i2c_smbus_write_byte_data(client,
 501                                              ADV7180_AUTODETECT_ENABLE_REG,
 502                                              ADV7180_AUTODETECT_DEFAULT);
 503                if (ret < 0)
 504                        return ret;
 505        } else {
 506                ret = v4l2_std_to_adv7180(state->curr_norm);
 507                if (ret < 0)
 508                        return ret;
 509
 510                ret =
 511                    i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
 512                                              ret | state->input);
 513                if (ret < 0)
 514                        return ret;
 515
 516        }
 517        /* ITU-R BT.656-4 compatible */
 518        ret = i2c_smbus_write_byte_data(client,
 519                        ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
 520                        ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
 521        if (ret < 0)
 522                return ret;
 523
 524        /* Manually set V bit end position in NTSC mode */
 525        ret = i2c_smbus_write_byte_data(client,
 526                                        ADV7180_NTSC_V_BIT_END_REG,
 527                                        ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
 528        if (ret < 0)
 529                return ret;
 530
 531        /* read current norm */
 532        __adv7180_status(client, NULL, &state->curr_norm);
 533
 534        /* register for interrupts */
 535        if (state->irq > 0) {
 536                ret = request_irq(state->irq, adv7180_irq, 0, KBUILD_MODNAME,
 537                                  state);
 538                if (ret)
 539                        return ret;
 540
 541                ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
 542                                                ADV7180_ADI_CTRL_IRQ_SPACE);
 543                if (ret < 0)
 544                        return ret;
 545
 546                /* config the Interrupt pin to be active low */
 547                ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
 548                                                ADV7180_ICONF1_ACTIVE_LOW |
 549                                                ADV7180_ICONF1_PSYNC_ONLY);
 550                if (ret < 0)
 551                        return ret;
 552
 553                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
 554                if (ret < 0)
 555                        return ret;
 556
 557                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
 558                if (ret < 0)
 559                        return ret;
 560
 561                /* enable AD change interrupts interrupts */
 562                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
 563                                                ADV7180_IRQ3_AD_CHANGE);
 564                if (ret < 0)
 565                        return ret;
 566
 567                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
 568                if (ret < 0)
 569                        return ret;
 570
 571                ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
 572                                                0);
 573                if (ret < 0)
 574                        return ret;
 575        }
 576
 577        return 0;
 578}
 579
 580static int adv7180_probe(struct i2c_client *client,
 581                         const struct i2c_device_id *id)
 582{
 583        struct adv7180_state *state;
 584        struct v4l2_subdev *sd;
 585        int ret;
 586
 587        /* Check if the adapter supports the needed features */
 588        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 589                return -EIO;
 590
 591        v4l_info(client, "chip found @ 0x%02x (%s)\n",
 592                 client->addr, client->adapter->name);
 593
 594        state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 595        if (state == NULL) {
 596                ret = -ENOMEM;
 597                goto err;
 598        }
 599
 600        state->irq = client->irq;
 601        INIT_WORK(&state->work, adv7180_work);
 602        mutex_init(&state->mutex);
 603        state->autodetect = true;
 604        state->input = 0;
 605        sd = &state->sd;
 606        v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
 607
 608        ret = adv7180_init_controls(state);
 609        if (ret)
 610                goto err_unreg_subdev;
 611        ret = init_device(client, state);
 612        if (ret)
 613                goto err_free_ctrl;
 614        return 0;
 615
 616err_free_ctrl:
 617        adv7180_exit_controls(state);
 618err_unreg_subdev:
 619        mutex_destroy(&state->mutex);
 620        v4l2_device_unregister_subdev(sd);
 621err:
 622        printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
 623        return ret;
 624}
 625
 626static int adv7180_remove(struct i2c_client *client)
 627{
 628        struct v4l2_subdev *sd = i2c_get_clientdata(client);
 629        struct adv7180_state *state = to_state(sd);
 630
 631        if (state->irq > 0) {
 632                free_irq(client->irq, state);
 633                if (cancel_work_sync(&state->work)) {
 634                        /*
 635                         * Work was pending, therefore we need to enable
 636                         * IRQ here to balance the disable_irq() done in the
 637                         * interrupt handler.
 638                         */
 639                        enable_irq(state->irq);
 640                }
 641        }
 642
 643        mutex_destroy(&state->mutex);
 644        v4l2_device_unregister_subdev(sd);
 645        return 0;
 646}
 647
 648static const struct i2c_device_id adv7180_id[] = {
 649        {KBUILD_MODNAME, 0},
 650        {},
 651};
 652
 653#ifdef CONFIG_PM_SLEEP
 654static int adv7180_suspend(struct device *dev)
 655{
 656        struct i2c_client *client = to_i2c_client(dev);
 657        int ret;
 658
 659        ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
 660                                        ADV7180_PWR_MAN_OFF);
 661        if (ret < 0)
 662                return ret;
 663        return 0;
 664}
 665
 666static int adv7180_resume(struct device *dev)
 667{
 668        struct i2c_client *client = to_i2c_client(dev);
 669        struct v4l2_subdev *sd = i2c_get_clientdata(client);
 670        struct adv7180_state *state = to_state(sd);
 671        int ret;
 672
 673        ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
 674                                        ADV7180_PWR_MAN_ON);
 675        if (ret < 0)
 676                return ret;
 677        ret = init_device(client, state);
 678        if (ret < 0)
 679                return ret;
 680        return 0;
 681}
 682
 683static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
 684#define ADV7180_PM_OPS (&adv7180_pm_ops)
 685
 686#else
 687#define ADV7180_PM_OPS NULL
 688#endif
 689
 690MODULE_DEVICE_TABLE(i2c, adv7180_id);
 691
 692static struct i2c_driver adv7180_driver = {
 693        .driver = {
 694                   .owner = THIS_MODULE,
 695                   .name = KBUILD_MODNAME,
 696                   .pm = ADV7180_PM_OPS,
 697                   },
 698        .probe = adv7180_probe,
 699        .remove = adv7180_remove,
 700        .id_table = adv7180_id,
 701};
 702
 703module_i2c_driver(adv7180_driver);
 704
 705MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
 706MODULE_AUTHOR("Mocean Laboratories");
 707MODULE_LICENSE("GPL v2");
 708