linux/drivers/staging/go7007/s2250-board.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008 Sensoray Company Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License (Version 2) as
   6 * published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program; if not, write to the Free Software Foundation,
  15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/init.h>
  20#include <linux/usb.h>
  21#include <linux/i2c.h>
  22#include <linux/videodev2.h>
  23#include <linux/slab.h>
  24#include <media/v4l2-device.h>
  25#include <media/v4l2-common.h>
  26#include <media/v4l2-subdev.h>
  27#include "go7007-priv.h"
  28
  29MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
  30MODULE_LICENSE("GPL v2");
  31
  32#define TLV320_ADDRESS      0x34
  33#define VPX322_ADDR_ANALOGCONTROL1      0x02
  34#define VPX322_ADDR_BRIGHTNESS0         0x0127
  35#define VPX322_ADDR_BRIGHTNESS1         0x0131
  36#define VPX322_ADDR_CONTRAST0           0x0128
  37#define VPX322_ADDR_CONTRAST1           0x0132
  38#define VPX322_ADDR_HUE                 0x00dc
  39#define VPX322_ADDR_SAT                 0x0030
  40
  41struct go7007_usb_board {
  42        unsigned int flags;
  43        struct go7007_board_info main_info;
  44};
  45
  46struct go7007_usb {
  47        struct go7007_usb_board *board;
  48        struct mutex i2c_lock;
  49        struct usb_device *usbdev;
  50        struct urb *video_urbs[8];
  51        struct urb *audio_urbs[8];
  52        struct urb *intr_urb;
  53};
  54
  55static unsigned char aud_regs[] = {
  56        0x1e, 0x00,
  57        0x00, 0x17,
  58        0x02, 0x17,
  59        0x04, 0xf9,
  60        0x06, 0xf9,
  61        0x08, 0x02,
  62        0x0a, 0x00,
  63        0x0c, 0x00,
  64        0x0a, 0x00,
  65        0x0c, 0x00,
  66        0x0e, 0x02,
  67        0x10, 0x00,
  68        0x12, 0x01,
  69        0x00, 0x00,
  70};
  71
  72
  73static unsigned char vid_regs[] = {
  74        0xF2, 0x0f,
  75        0xAA, 0x00,
  76        0xF8, 0xff,
  77        0x00, 0x00,
  78};
  79
  80static u16 vid_regs_fp[] = {
  81        0x028, 0x067,
  82        0x120, 0x016,
  83        0x121, 0xcF2,
  84        0x122, 0x0F2,
  85        0x123, 0x00c,
  86        0x124, 0x2d0,
  87        0x125, 0x2e0,
  88        0x126, 0x004,
  89        0x128, 0x1E0,
  90        0x12A, 0x016,
  91        0x12B, 0x0F2,
  92        0x12C, 0x0F2,
  93        0x12D, 0x00c,
  94        0x12E, 0x2d0,
  95        0x12F, 0x2e0,
  96        0x130, 0x004,
  97        0x132, 0x1E0,
  98        0x140, 0x060,
  99        0x153, 0x00C,
 100        0x154, 0x200,
 101        0x150, 0x801,
 102        0x000, 0x000
 103};
 104
 105/* PAL specific values */
 106static u16 vid_regs_fp_pal[] =
 107{
 108        0x120, 0x017,
 109        0x121, 0xd22,
 110        0x122, 0x122,
 111        0x12A, 0x017,
 112        0x12B, 0x122,
 113        0x12C, 0x122,
 114        0x140, 0x060,
 115        0x000, 0x000,
 116};
 117
 118struct s2250 {
 119        struct v4l2_subdev sd;
 120        v4l2_std_id std;
 121        int input;
 122        int brightness;
 123        int contrast;
 124        int saturation;
 125        int hue;
 126        int reg12b_val;
 127        int audio_input;
 128        struct i2c_client *audio;
 129};
 130
 131static inline struct s2250 *to_state(struct v4l2_subdev *sd)
 132{
 133        return container_of(sd, struct s2250, sd);
 134}
 135
 136/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
 137static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
 138        u16 value, u16 index, void *transfer_buffer, int length, int in)
 139{
 140        struct go7007_usb *usb = go->hpi_context;
 141        int timeout = 5000;
 142
 143        if (in) {
 144                return usb_control_msg(usb->usbdev,
 145                                usb_rcvctrlpipe(usb->usbdev, 0), request,
 146                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 147                                value, index, transfer_buffer, length, timeout);
 148        } else {
 149                return usb_control_msg(usb->usbdev,
 150                                usb_sndctrlpipe(usb->usbdev, 0), request,
 151                                USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 152                                value, index, transfer_buffer, length, timeout);
 153        }
 154}
 155/* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
 156
 157static int write_reg(struct i2c_client *client, u8 reg, u8 value)
 158{
 159        struct go7007 *go = i2c_get_adapdata(client->adapter);
 160        struct go7007_usb *usb;
 161        int rc;
 162        int dev_addr = client->addr << 1;  /* firmware wants 8-bit address */
 163        u8 *buf;
 164
 165        if (go == NULL)
 166                return -ENODEV;
 167
 168        if (go->status == STATUS_SHUTDOWN)
 169                return -EBUSY;
 170
 171        buf = kzalloc(16, GFP_KERNEL);
 172        if (buf == NULL)
 173                return -ENOMEM;
 174
 175        usb = go->hpi_context;
 176        if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 177                printk(KERN_INFO "i2c lock failed\n");
 178                kfree(buf);
 179                return -EINTR;
 180        }
 181        rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
 182                                       (reg<<8 | value),
 183                                       buf,
 184                                       16, 1);
 185
 186        mutex_unlock(&usb->i2c_lock);
 187        kfree(buf);
 188        return rc;
 189}
 190
 191static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
 192{
 193        struct go7007 *go = i2c_get_adapdata(client->adapter);
 194        struct go7007_usb *usb;
 195        u8 *buf;
 196        struct s2250 *dec = i2c_get_clientdata(client);
 197
 198        if (go == NULL)
 199                return -ENODEV;
 200
 201        if (go->status == STATUS_SHUTDOWN)
 202                return -EBUSY;
 203
 204        buf = kzalloc(16, GFP_KERNEL);
 205
 206        if (buf == NULL)
 207                return -ENOMEM;
 208
 209
 210
 211        memset(buf, 0xcd, 6);
 212
 213        usb = go->hpi_context;
 214        if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 215                printk(KERN_INFO "i2c lock failed\n");
 216                kfree(buf);
 217                return -EINTR;
 218        }
 219        if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) {
 220                kfree(buf);
 221                return -EFAULT;
 222        }
 223
 224        mutex_unlock(&usb->i2c_lock);
 225        if (buf[0] == 0) {
 226                unsigned int subaddr, val_read;
 227
 228                subaddr = (buf[4] << 8) + buf[5];
 229                val_read = (buf[2] << 8) + buf[3];
 230                kfree(buf);
 231                if (val_read != val) {
 232                        printk(KERN_INFO "invalid fp write %x %x\n",
 233                               val_read, val);
 234                        return -EFAULT;
 235                }
 236                if (subaddr != addr) {
 237                        printk(KERN_INFO "invalid fp write addr %x %x\n",
 238                               subaddr, addr);
 239                        return -EFAULT;
 240                }
 241        } else {
 242                kfree(buf);
 243                return -EFAULT;
 244        }
 245
 246        /* save last 12b value */
 247        if (addr == 0x12b)
 248                dec->reg12b_val = val;
 249
 250        return 0;
 251}
 252
 253static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
 254{
 255        struct go7007 *go = i2c_get_adapdata(client->adapter);
 256        struct go7007_usb *usb;
 257        u8 *buf;
 258
 259        if (go == NULL)
 260                return -ENODEV;
 261
 262        if (go->status == STATUS_SHUTDOWN)
 263                return -EBUSY;
 264
 265        buf = kzalloc(16, GFP_KERNEL);
 266
 267        if (buf == NULL)
 268                return -ENOMEM;
 269
 270
 271
 272        memset(buf, 0xcd, 6);
 273        usb = go->hpi_context;
 274        if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 275                printk(KERN_INFO "i2c lock failed\n");
 276                kfree(buf);
 277                return -EINTR;
 278        }
 279        if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) {
 280                kfree(buf);
 281                return -EFAULT;
 282        }
 283        mutex_unlock(&usb->i2c_lock);
 284
 285        *val = (buf[0] << 8) | buf[1];
 286        kfree(buf);
 287
 288        return 0;
 289}
 290
 291
 292static int write_regs(struct i2c_client *client, u8 *regs)
 293{
 294        int i;
 295
 296        for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
 297                if (write_reg(client, regs[i], regs[i+1]) < 0) {
 298                        printk(KERN_INFO "s2250: failed\n");
 299                        return -1;
 300                }
 301        }
 302        return 0;
 303}
 304
 305static int write_regs_fp(struct i2c_client *client, u16 *regs)
 306{
 307        int i;
 308
 309        for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
 310                if (write_reg_fp(client, regs[i], regs[i+1]) < 0) {
 311                        printk(KERN_INFO "s2250: failed fp\n");
 312                        return -1;
 313                }
 314        }
 315        return 0;
 316}
 317
 318
 319/* ------------------------------------------------------------------------- */
 320
 321static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
 322                                 u32 config)
 323{
 324        struct s2250 *state = to_state(sd);
 325        struct i2c_client *client = v4l2_get_subdevdata(sd);
 326        int vidsys;
 327
 328        vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
 329        if (input == 0) {
 330                /* composite */
 331                write_reg_fp(client, 0x20, 0x020 | vidsys);
 332                write_reg_fp(client, 0x21, 0x662);
 333                write_reg_fp(client, 0x140, 0x060);
 334        } else if (input == 1) {
 335                /* S-Video */
 336                write_reg_fp(client, 0x20, 0x040 | vidsys);
 337                write_reg_fp(client, 0x21, 0x666);
 338                write_reg_fp(client, 0x140, 0x060);
 339        } else {
 340                return -EINVAL;
 341        }
 342        state->input = input;
 343        return 0;
 344}
 345
 346static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 347{
 348        struct s2250 *state = to_state(sd);
 349        struct i2c_client *client = v4l2_get_subdevdata(sd);
 350        u16 vidsource;
 351
 352        vidsource = (state->input == 1) ? 0x040 : 0x020;
 353        switch (norm) {
 354        case V4L2_STD_NTSC:
 355                write_regs_fp(client, vid_regs_fp);
 356                write_reg_fp(client, 0x20, vidsource | 1);
 357                break;
 358        case V4L2_STD_PAL:
 359                write_regs_fp(client, vid_regs_fp);
 360                write_regs_fp(client, vid_regs_fp_pal);
 361                write_reg_fp(client, 0x20, vidsource);
 362                break;
 363        default:
 364                return -EINVAL;
 365        }
 366        state->std = norm;
 367        return 0;
 368}
 369
 370static int s2250_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query)
 371{
 372        switch (query->id) {
 373        case V4L2_CID_BRIGHTNESS:
 374                return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
 375        case V4L2_CID_CONTRAST:
 376                return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
 377        case V4L2_CID_SATURATION:
 378                return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
 379        case V4L2_CID_HUE:
 380                return v4l2_ctrl_query_fill(query, -50, 50, 1, 0);
 381        default:
 382                return -EINVAL;
 383        }
 384        return 0;
 385}
 386
 387static int s2250_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 388{
 389        struct s2250 *state = to_state(sd);
 390        struct i2c_client *client = v4l2_get_subdevdata(sd);
 391        int value1;
 392        u16 oldvalue;
 393
 394        switch (ctrl->id) {
 395        case V4L2_CID_BRIGHTNESS:
 396                if (ctrl->value > 100)
 397                        state->brightness = 100;
 398                else if (ctrl->value < 0)
 399                        state->brightness = 0;
 400                else
 401                        state->brightness = ctrl->value;
 402                value1 = (state->brightness - 50) * 255 / 100;
 403                read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
 404                write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
 405                             value1 | (oldvalue & ~0xff));
 406                read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
 407                write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
 408                             value1 | (oldvalue & ~0xff));
 409                write_reg_fp(client, 0x140, 0x60);
 410                break;
 411        case V4L2_CID_CONTRAST:
 412                if (ctrl->value > 100)
 413                        state->contrast = 100;
 414                else if (ctrl->value < 0)
 415                        state->contrast = 0;
 416                else
 417                        state->contrast = ctrl->value;
 418                value1 = state->contrast * 0x40 / 100;
 419                if (value1 > 0x3f)
 420                        value1 = 0x3f; /* max */
 421                read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
 422                write_reg_fp(client, VPX322_ADDR_CONTRAST0,
 423                             value1 | (oldvalue & ~0x3f));
 424                read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
 425                write_reg_fp(client, VPX322_ADDR_CONTRAST1,
 426                             value1 | (oldvalue & ~0x3f));
 427                write_reg_fp(client, 0x140, 0x60);
 428                break;
 429        case V4L2_CID_SATURATION:
 430                if (ctrl->value > 100)
 431                        state->saturation = 100;
 432                else if (ctrl->value < 0)
 433                        state->saturation = 0;
 434                else
 435                        state->saturation = ctrl->value;
 436                value1 = state->saturation * 4140 / 100;
 437                if (value1 > 4094)
 438                        value1 = 4094;
 439                write_reg_fp(client, VPX322_ADDR_SAT, value1);
 440                break;
 441        case V4L2_CID_HUE:
 442                if (ctrl->value > 50)
 443                        state->hue = 50;
 444                else if (ctrl->value < -50)
 445                        state->hue = -50;
 446                else
 447                        state->hue = ctrl->value;
 448                /* clamp the hue range */
 449                value1 = state->hue * 280 / 50;
 450                write_reg_fp(client, VPX322_ADDR_HUE, value1);
 451                break;
 452        default:
 453                return -EINVAL;
 454        }
 455        return 0;
 456}
 457
 458static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 459{
 460        struct s2250 *state = to_state(sd);
 461
 462        switch (ctrl->id) {
 463        case V4L2_CID_BRIGHTNESS:
 464                ctrl->value = state->brightness;
 465                break;
 466        case V4L2_CID_CONTRAST:
 467                ctrl->value = state->contrast;
 468                break;
 469        case V4L2_CID_SATURATION:
 470                ctrl->value = state->saturation;
 471                break;
 472        case V4L2_CID_HUE:
 473                ctrl->value = state->hue;
 474                break;
 475        default:
 476                return -EINVAL;
 477        }
 478        return 0;
 479}
 480
 481static int s2250_s_mbus_fmt(struct v4l2_subdev *sd,
 482                        struct v4l2_mbus_framefmt *fmt)
 483{
 484        struct s2250 *state = to_state(sd);
 485        struct i2c_client *client = v4l2_get_subdevdata(sd);
 486
 487        if (fmt->height < 640) {
 488                write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
 489                write_reg_fp(client, 0x140, 0x060);
 490        } else {
 491                write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
 492                write_reg_fp(client, 0x140, 0x060);
 493        }
 494        return 0;
 495}
 496
 497static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
 498                                 u32 config)
 499{
 500        struct s2250 *state = to_state(sd);
 501
 502        switch (input) {
 503        case 0:
 504                write_reg(state->audio, 0x08, 0x02); /* Line In */
 505                break;
 506        case 1:
 507                write_reg(state->audio, 0x08, 0x04); /* Mic */
 508                break;
 509        case 2:
 510                write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
 511                break;
 512        default:
 513                return -EINVAL;
 514        }
 515        state->audio_input = input;
 516        return 0;
 517}
 518
 519
 520static int s2250_log_status(struct v4l2_subdev *sd)
 521{
 522        struct s2250 *state = to_state(sd);
 523
 524        v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
 525                                        state->std == V4L2_STD_PAL ? "PAL" :
 526                                        state->std == V4L2_STD_SECAM ? "SECAM" :
 527                                        "unknown");
 528        v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
 529                                        state->input == 1 ? "S-video" :
 530                                        "error");
 531        v4l2_info(sd, "Brightness: %d\n", state->brightness);
 532        v4l2_info(sd, "Contrast: %d\n", state->contrast);
 533        v4l2_info(sd, "Saturation: %d\n", state->saturation);
 534        v4l2_info(sd, "Hue: %d\n", state->hue); return 0;
 535        v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
 536                                        state->audio_input == 1 ? "Mic" :
 537                                        state->audio_input == 2 ? "Mic Boost" :
 538                                        "error");
 539        return 0;
 540}
 541
 542/* --------------------------------------------------------------------------*/
 543
 544static const struct v4l2_subdev_core_ops s2250_core_ops = {
 545        .log_status = s2250_log_status,
 546        .g_ctrl = s2250_g_ctrl,
 547        .s_ctrl = s2250_s_ctrl,
 548        .queryctrl = s2250_queryctrl,
 549        .s_std = s2250_s_std,
 550};
 551
 552static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
 553        .s_routing = s2250_s_audio_routing,
 554};
 555
 556static const struct v4l2_subdev_video_ops s2250_video_ops = {
 557        .s_routing = s2250_s_video_routing,
 558        .s_mbus_fmt = s2250_s_mbus_fmt,
 559};
 560
 561static const struct v4l2_subdev_ops s2250_ops = {
 562        .core = &s2250_core_ops,
 563        .audio = &s2250_audio_ops,
 564        .video = &s2250_video_ops,
 565};
 566
 567/* --------------------------------------------------------------------------*/
 568
 569static int s2250_probe(struct i2c_client *client,
 570                       const struct i2c_device_id *id)
 571{
 572        struct i2c_client *audio;
 573        struct i2c_adapter *adapter = client->adapter;
 574        struct s2250 *state;
 575        struct v4l2_subdev *sd;
 576        u8 *data;
 577        struct go7007 *go = i2c_get_adapdata(adapter);
 578        struct go7007_usb *usb = go->hpi_context;
 579
 580        audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
 581        if (audio == NULL)
 582                return -ENOMEM;
 583
 584        state = kmalloc(sizeof(struct s2250), GFP_KERNEL);
 585        if (state == NULL) {
 586                i2c_unregister_device(audio);
 587                return -ENOMEM;
 588        }
 589
 590        sd = &state->sd;
 591        v4l2_i2c_subdev_init(sd, client, &s2250_ops);
 592
 593        v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
 594               "Sensoray 2250/2251", client->addr, client->adapter->name);
 595
 596        state->std = V4L2_STD_NTSC;
 597        state->brightness = 50;
 598        state->contrast = 50;
 599        state->saturation = 50;
 600        state->hue = 0;
 601        state->audio = audio;
 602
 603        /* initialize the audio */
 604        if (write_regs(audio, aud_regs) < 0) {
 605                printk(KERN_ERR
 606                       "s2250: error initializing audio\n");
 607                i2c_unregister_device(audio);
 608                kfree(state);
 609                return 0;
 610        }
 611
 612        if (write_regs(client, vid_regs) < 0) {
 613                printk(KERN_ERR
 614                       "s2250: error initializing decoder\n");
 615                i2c_unregister_device(audio);
 616                kfree(state);
 617                return 0;
 618        }
 619        if (write_regs_fp(client, vid_regs_fp) < 0) {
 620                printk(KERN_ERR
 621                       "s2250: error initializing decoder\n");
 622                i2c_unregister_device(audio);
 623                kfree(state);
 624                return 0;
 625        }
 626        /* set default channel */
 627        /* composite */
 628        write_reg_fp(client, 0x20, 0x020 | 1);
 629        write_reg_fp(client, 0x21, 0x662);
 630        write_reg_fp(client, 0x140, 0x060);
 631
 632        /* set default audio input */
 633        state->audio_input = 0;
 634        write_reg(client, 0x08, 0x02); /* Line In */
 635
 636        if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
 637                data = kzalloc(16, GFP_KERNEL);
 638                if (data != NULL) {
 639                        int rc;
 640                        rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
 641                                                       data, 16, 1);
 642                        if (rc > 0) {
 643                                u8 mask;
 644                                data[0] = 0;
 645                                mask = 1<<5;
 646                                data[0] &= ~mask;
 647                                data[1] |= mask;
 648                                go7007_usb_vendor_request(go, 0x40, 0,
 649                                                          (data[1]<<8)
 650                                                          + data[1],
 651                                                          data, 16, 0);
 652                        }
 653                        kfree(data);
 654                }
 655                mutex_unlock(&usb->i2c_lock);
 656        }
 657
 658        v4l2_info(sd, "initialized successfully\n");
 659        return 0;
 660}
 661
 662static int s2250_remove(struct i2c_client *client)
 663{
 664        struct v4l2_subdev *sd = i2c_get_clientdata(client);
 665
 666        v4l2_device_unregister_subdev(sd);
 667        kfree(to_state(sd));
 668        return 0;
 669}
 670
 671static const struct i2c_device_id s2250_id[] = {
 672        { "s2250", 0 },
 673        { }
 674};
 675MODULE_DEVICE_TABLE(i2c, s2250_id);
 676
 677static struct i2c_driver s2250_driver = {
 678        .driver = {
 679                .owner  = THIS_MODULE,
 680                .name   = "s2250",
 681        },
 682        .probe          = s2250_probe,
 683        .remove         = s2250_remove,
 684        .id_table       = s2250_id,
 685};
 686
 687static __init int init_s2250(void)
 688{
 689        return i2c_add_driver(&s2250_driver);
 690}
 691
 692static __exit void exit_s2250(void)
 693{
 694        i2c_del_driver(&s2250_driver);
 695}
 696
 697module_init(init_s2250);
 698module_exit(exit_s2250);
 699