1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * A driver for the CMOS camera controller in the Marvell 88ALP01 "cafe" 4 * multifunction chip. Currently works with the Omnivision OV7670 5 * sensor. 6 * 7 * The data sheet for this device can be found at: 8 * http://wiki.laptop.org/images/5/5c/88ALP01_Datasheet_July_2007.pdf 9 * 10 * Copyright 2006-11 One Laptop Per Child Association, Inc. 11 * Copyright 2006-11 Jonathan Corbet <corbet@lwn.net> 12 * Copyright 2018 Lubomir Rintel <lkundrak@v3.sk> 13 * 14 * Written by Jonathan Corbet, corbet@lwn.net. 15 * 16 * v4l2_device/v4l2_subdev conversion by: 17 * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl> 18 */ 19#include <linux/kernel.h> 20#include <linux/module.h> 21#include <linux/init.h> 22#include <linux/pci.h> 23#include <linux/i2c.h> 24#include <linux/interrupt.h> 25#include <linux/spinlock.h> 26#include <linux/slab.h> 27#include <linux/videodev2.h> 28#include <media/v4l2-device.h> 29#include <media/i2c/ov7670.h> 30#include <linux/device.h> 31#include <linux/wait.h> 32#include <linux/delay.h> 33#include <linux/io.h> 34#include <linux/clkdev.h> 35 36#include "mcam-core.h" 37 38#define CAFE_VERSION 0x000002 39 40 41/* 42 * Parameters. 43 */ 44MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); 45MODULE_DESCRIPTION("Marvell 88ALP01 CMOS Camera Controller driver"); 46MODULE_LICENSE("GPL"); 47MODULE_SUPPORTED_DEVICE("Video"); 48 49 50 51 52struct cafe_camera { 53 int registered; /* Fully initialized? */ 54 struct mcam_camera mcam; 55 struct pci_dev *pdev; 56 struct i2c_adapter *i2c_adapter; 57 wait_queue_head_t smbus_wait; /* Waiting on i2c events */ 58}; 59 60/* 61 * Most of the camera controller registers are defined in mcam-core.h, 62 * but the Cafe platform has some additional registers of its own; 63 * they are described here. 64 */ 65 66/* 67 * "General purpose register" has a couple of GPIOs used for sensor 68 * power and reset on OLPC XO 1.0 systems. 69 */ 70#define REG_GPR 0xb4 71#define GPR_C1EN 0x00000020 /* Pad 1 (power down) enable */ 72#define GPR_C0EN 0x00000010 /* Pad 0 (reset) enable */ 73#define GPR_C1 0x00000002 /* Control 1 value */ 74/* 75 * Control 0 is wired to reset on OLPC machines. For ov7x sensors, 76 * it is active low. 77 */ 78#define GPR_C0 0x00000001 /* Control 0 value */ 79 80/* 81 * These registers control the SMBUS module for communicating 82 * with the sensor. 83 */ 84#define REG_TWSIC0 0xb8 /* TWSI (smbus) control 0 */ 85#define TWSIC0_EN 0x00000001 /* TWSI enable */ 86#define TWSIC0_MODE 0x00000002 /* 1 = 16-bit, 0 = 8-bit */ 87#define TWSIC0_SID 0x000003fc /* Slave ID */ 88/* 89 * Subtle trickery: the slave ID field starts with bit 2. But the 90 * Linux i2c stack wants to treat the bottommost bit as a separate 91 * read/write bit, which is why slave ID's are usually presented 92 * >>1. For consistency with that behavior, we shift over three 93 * bits instead of two. 94 */ 95#define TWSIC0_SID_SHIFT 3 96#define TWSIC0_CLKDIV 0x0007fc00 /* Clock divider */ 97#define TWSIC0_MASKACK 0x00400000 /* Mask ack from sensor */ 98#define TWSIC0_OVMAGIC 0x00800000 /* Make it work on OV sensors */ 99 100#define REG_TWSIC1 0xbc /* TWSI control 1 */ 101#define TWSIC1_DATA 0x0000ffff /* Data to/from camchip */ 102#define TWSIC1_ADDR 0x00ff0000 /* Address (register) */ 103#define TWSIC1_ADDR_SHIFT 16 104#define TWSIC1_READ 0x01000000 /* Set for read op */ 105#define TWSIC1_WSTAT 0x02000000 /* Write status */ 106#define TWSIC1_RVALID 0x04000000 /* Read data valid */ 107#define TWSIC1_ERROR 0x08000000 /* Something screwed up */ 108 109/* 110 * Here's the weird global control registers 111 */ 112#define REG_GL_CSR 0x3004 /* Control/status register */ 113#define GCSR_SRS 0x00000001 /* SW Reset set */ 114#define GCSR_SRC 0x00000002 /* SW Reset clear */ 115#define GCSR_MRS 0x00000004 /* Master reset set */ 116#define GCSR_MRC 0x00000008 /* HW Reset clear */ 117#define GCSR_CCIC_EN 0x00004000 /* CCIC Clock enable */ 118#define REG_GL_IMASK 0x300c /* Interrupt mask register */ 119#define GIMSK_CCIC_EN 0x00000004 /* CCIC Interrupt enable */ 120 121#define REG_GL_FCR 0x3038 /* GPIO functional control register */ 122#define GFCR_GPIO_ON 0x08 /* Camera GPIO enabled */ 123#define REG_GL_GPIOR 0x315c /* GPIO register */ 124#define GGPIO_OUT 0x80000 /* GPIO output */ 125#define GGPIO_VAL 0x00008 /* Output pin value */ 126 127#define REG_LEN (REG_GL_IMASK + 4) 128 129 130/* 131 * Debugging and related. 132 */ 133#define cam_err(cam, fmt, arg...) \ 134 dev_err(&(cam)->pdev->dev, fmt, ##arg); 135#define cam_warn(cam, fmt, arg...) \ 136 dev_warn(&(cam)->pdev->dev, fmt, ##arg); 137 138/* -------------------------------------------------------------------- */ 139/* 140 * The I2C/SMBUS interface to the camera itself starts here. The 141 * controller handles SMBUS itself, presenting a relatively simple register 142 * interface; all we have to do is to tell it where to route the data. 143 */ 144#define CAFE_SMBUS_TIMEOUT (HZ) /* generous */ 145 146static inline struct cafe_camera *to_cam(struct v4l2_device *dev) 147{ 148 struct mcam_camera *m = container_of(dev, struct mcam_camera, v4l2_dev); 149 return container_of(m, struct cafe_camera, mcam); 150} 151 152 153static int cafe_smbus_write_done(struct mcam_camera *mcam) 154{ 155 unsigned long flags; 156 int c1; 157 158 /* 159 * We must delay after the interrupt, or the controller gets confused 160 * and never does give us good status. Fortunately, we don't do this 161 * often. 162 */ 163 udelay(20); 164 spin_lock_irqsave(&mcam->dev_lock, flags); 165 c1 = mcam_reg_read(mcam, REG_TWSIC1); 166 spin_unlock_irqrestore(&mcam->dev_lock, flags); 167 return (c1 & (TWSIC1_WSTAT|TWSIC1_ERROR)) != TWSIC1_WSTAT; 168} 169 170static int cafe_smbus_write_data(struct cafe_camera *cam, 171 u16 addr, u8 command, u8 value) 172{ 173 unsigned int rval; 174 unsigned long flags; 175 struct mcam_camera *mcam = &cam->mcam; 176 177 spin_lock_irqsave(&mcam->dev_lock, flags); 178 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); 179 rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */ 180 /* 181 * Marvell sez set clkdiv to all 1's for now. 182 */ 183 rval |= TWSIC0_CLKDIV; 184 mcam_reg_write(mcam, REG_TWSIC0, rval); 185 (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */ 186 rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); 187 mcam_reg_write(mcam, REG_TWSIC1, rval); 188 spin_unlock_irqrestore(&mcam->dev_lock, flags); 189 190 /* Unfortunately, reading TWSIC1 too soon after sending a command 191 * causes the device to die. 192 * Use a busy-wait because we often send a large quantity of small 193 * commands at-once; using msleep() would cause a lot of context 194 * switches which take longer than 2ms, resulting in a noticeable 195 * boot-time and capture-start delays. 196 */ 197 mdelay(2); 198 199 /* 200 * Another sad fact is that sometimes, commands silently complete but 201 * cafe_smbus_write_done() never becomes aware of this. 202 * This happens at random and appears to possible occur with any 203 * command. 204 * We don't understand why this is. We work around this issue 205 * with the timeout in the wait below, assuming that all commands 206 * complete within the timeout. 207 */ 208 wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(mcam), 209 CAFE_SMBUS_TIMEOUT); 210 211 spin_lock_irqsave(&mcam->dev_lock, flags); 212 rval = mcam_reg_read(mcam, REG_TWSIC1); 213 spin_unlock_irqrestore(&mcam->dev_lock, flags); 214 215 if (rval & TWSIC1_WSTAT) { 216 cam_err(cam, "SMBUS write (%02x/%02x/%02x) timed out\n", addr, 217 command, value); 218 return -EIO; 219 } 220 if (rval & TWSIC1_ERROR) { 221 cam_err(cam, "SMBUS write (%02x/%02x/%02x) error\n", addr, 222 command, value); 223 return -EIO; 224 } 225 return 0; 226} 227 228 229 230static int cafe_smbus_read_done(struct mcam_camera *mcam) 231{ 232 unsigned long flags; 233 int c1; 234 235 /* 236 * We must delay after the interrupt, or the controller gets confused 237 * and never does give us good status. Fortunately, we don't do this 238 * often. 239 */ 240 udelay(20); 241 spin_lock_irqsave(&mcam->dev_lock, flags); 242 c1 = mcam_reg_read(mcam, REG_TWSIC1); 243 spin_unlock_irqrestore(&mcam->dev_lock, flags); 244 return c1 & (TWSIC1_RVALID|TWSIC1_ERROR); 245} 246 247 248 249static int cafe_smbus_read_data(struct cafe_camera *cam, 250 u16 addr, u8 command, u8 *value) 251{ 252 unsigned int rval; 253 unsigned long flags; 254 struct mcam_camera *mcam = &cam->mcam; 255 256 spin_lock_irqsave(&mcam->dev_lock, flags); 257 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); 258 rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */ 259 /* 260 * Marvel sez set clkdiv to all 1's for now. 261 */ 262 rval |= TWSIC0_CLKDIV; 263 mcam_reg_write(mcam, REG_TWSIC0, rval); 264 (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */ 265 rval = TWSIC1_READ | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); 266 mcam_reg_write(mcam, REG_TWSIC1, rval); 267 spin_unlock_irqrestore(&mcam->dev_lock, flags); 268 269 wait_event_timeout(cam->smbus_wait, 270 cafe_smbus_read_done(mcam), CAFE_SMBUS_TIMEOUT); 271 spin_lock_irqsave(&mcam->dev_lock, flags); 272 rval = mcam_reg_read(mcam, REG_TWSIC1); 273 spin_unlock_irqrestore(&mcam->dev_lock, flags); 274 275 if (rval & TWSIC1_ERROR) { 276 cam_err(cam, "SMBUS read (%02x/%02x) error\n", addr, command); 277 return -EIO; 278 } 279 if (!(rval & TWSIC1_RVALID)) { 280 cam_err(cam, "SMBUS read (%02x/%02x) timed out\n", addr, 281 command); 282 return -EIO; 283 } 284 *value = rval & 0xff; 285 return 0; 286} 287 288/* 289 * Perform a transfer over SMBUS. This thing is called under 290 * the i2c bus lock, so we shouldn't race with ourselves... 291 */ 292static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr, 293 unsigned short flags, char rw, u8 command, 294 int size, union i2c_smbus_data *data) 295{ 296 struct cafe_camera *cam = i2c_get_adapdata(adapter); 297 int ret = -EINVAL; 298 299 /* 300 * This interface would appear to only do byte data ops. OK 301 * it can do word too, but the cam chip has no use for that. 302 */ 303 if (size != I2C_SMBUS_BYTE_DATA) { 304 cam_err(cam, "funky xfer size %d\n", size); 305 return -EINVAL; 306 } 307 308 if (rw == I2C_SMBUS_WRITE) 309 ret = cafe_smbus_write_data(cam, addr, command, data->byte); 310 else if (rw == I2C_SMBUS_READ) 311 ret = cafe_smbus_read_data(cam, addr, command, &data->byte); 312 return ret; 313} 314 315 316static void cafe_smbus_enable_irq(struct cafe_camera *cam) 317{ 318 unsigned long flags; 319 320 spin_lock_irqsave(&cam->mcam.dev_lock, flags); 321 mcam_reg_set_bit(&cam->mcam, REG_IRQMASK, TWSIIRQS); 322 spin_unlock_irqrestore(&cam->mcam.dev_lock, flags); 323} 324 325static u32 cafe_smbus_func(struct i2c_adapter *adapter) 326{ 327 return I2C_FUNC_SMBUS_READ_BYTE_DATA | 328 I2C_FUNC_SMBUS_WRITE_BYTE_DATA; 329} 330 331static const struct i2c_algorithm cafe_smbus_algo = { 332 .smbus_xfer = cafe_smbus_xfer, 333 .functionality = cafe_smbus_func 334}; 335 336static int cafe_smbus_setup(struct cafe_camera *cam) 337{ 338 struct i2c_adapter *adap; 339 int ret; 340 341 adap = kzalloc(sizeof(*adap), GFP_KERNEL); 342 if (adap == NULL) 343 return -ENOMEM; 344 adap->owner = THIS_MODULE; 345 adap->algo = &cafe_smbus_algo; 346 strscpy(adap->name, "cafe_ccic", sizeof(adap->name)); 347 adap->dev.parent = &cam->pdev->dev; 348 i2c_set_adapdata(adap, cam); 349 ret = i2c_add_adapter(adap); 350 if (ret) { 351 printk(KERN_ERR "Unable to register cafe i2c adapter\n"); 352 kfree(adap); 353 return ret; 354 } 355 356 cam->i2c_adapter = adap; 357 cafe_smbus_enable_irq(cam); 358 return 0; 359} 360 361static void cafe_smbus_shutdown(struct cafe_camera *cam) 362{ 363 i2c_del_adapter(cam->i2c_adapter); 364 kfree(cam->i2c_adapter); 365} 366 367 368/* 369 * Controller-level stuff 370 */ 371 372static void cafe_ctlr_init(struct mcam_camera *mcam) 373{ 374 unsigned long flags; 375 376 spin_lock_irqsave(&mcam->dev_lock, flags); 377 /* 378 * Added magic to bring up the hardware on the B-Test board 379 */ 380 mcam_reg_write(mcam, 0x3038, 0x8); 381 mcam_reg_write(mcam, 0x315c, 0x80008); 382 /* 383 * Go through the dance needed to wake the device up. 384 * Note that these registers are global and shared 385 * with the NAND and SD devices. Interaction between the 386 * three still needs to be examined. 387 */ 388 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */ 389 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRC); 390 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRS); 391 /* 392 * Here we must wait a bit for the controller to come around. 393 */ 394 spin_unlock_irqrestore(&mcam->dev_lock, flags); 395 msleep(5); 396 spin_lock_irqsave(&mcam->dev_lock, flags); 397 398 mcam_reg_write(mcam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC); 399 mcam_reg_set_bit(mcam, REG_GL_IMASK, GIMSK_CCIC_EN); 400 /* 401 * Mask all interrupts. 402 */ 403 mcam_reg_write(mcam, REG_IRQMASK, 0); 404 spin_unlock_irqrestore(&mcam->dev_lock, flags); 405} 406 407 408static int cafe_ctlr_power_up(struct mcam_camera *mcam) 409{ 410 /* 411 * Part one of the sensor dance: turn the global 412 * GPIO signal on. 413 */ 414 mcam_reg_write(mcam, REG_GL_FCR, GFCR_GPIO_ON); 415 mcam_reg_write(mcam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL); 416 /* 417 * Put the sensor into operational mode (assumes OLPC-style 418 * wiring). Control 0 is reset - set to 1 to operate. 419 * Control 1 is power down, set to 0 to operate. 420 */ 421 mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */ 422 mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); 423 424 return 0; 425} 426 427static void cafe_ctlr_power_down(struct mcam_camera *mcam) 428{ 429 mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1); 430 mcam_reg_write(mcam, REG_GL_FCR, GFCR_GPIO_ON); 431 mcam_reg_write(mcam, REG_GL_GPIOR, GGPIO_OUT); 432} 433 434 435 436/* 437 * The platform interrupt handler. 438 */ 439static irqreturn_t cafe_irq(int irq, void *data) 440{ 441 struct cafe_camera *cam = data; 442 struct mcam_camera *mcam = &cam->mcam; 443 unsigned int irqs, handled; 444 445 spin_lock(&mcam->dev_lock); 446 irqs = mcam_reg_read(mcam, REG_IRQSTAT); 447 handled = cam->registered && mccic_irq(mcam, irqs); 448 if (irqs & TWSIIRQS) { 449 mcam_reg_write(mcam, REG_IRQSTAT, TWSIIRQS); 450 wake_up(&cam->smbus_wait); 451 handled = 1; 452 } 453 spin_unlock(&mcam->dev_lock); 454 return IRQ_RETVAL(handled); 455} 456 457/* -------------------------------------------------------------------------- */ 458 459static struct ov7670_config sensor_cfg = { 460 /* 461 * Exclude QCIF mode, because it only captures a tiny portion 462 * of the sensor FOV 463 */ 464 .min_width = 320, 465 .min_height = 240, 466 467 /* 468 * Set the clock speed for the XO 1; I don't believe this 469 * driver has ever run anywhere else. 470 */ 471 .clock_speed = 45, 472 .use_smbus = 1, 473}; 474 475static struct i2c_board_info ov7670_info = { 476 .type = "ov7670", 477 .addr = 0x42 >> 1, 478 .platform_data = &sensor_cfg, 479}; 480 481/* -------------------------------------------------------------------------- */ 482/* 483 * PCI interface stuff. 484 */ 485 486static int cafe_pci_probe(struct pci_dev *pdev, 487 const struct pci_device_id *id) 488{ 489 int ret; 490 struct cafe_camera *cam; 491 struct mcam_camera *mcam; 492 493 /* 494 * Start putting together one of our big camera structures. 495 */ 496 ret = -ENOMEM; 497 cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL); 498 if (cam == NULL) 499 goto out; 500 pci_set_drvdata(pdev, cam); 501 cam->pdev = pdev; 502 mcam = &cam->mcam; 503 mcam->chip_id = MCAM_CAFE; 504 spin_lock_init(&mcam->dev_lock); 505 init_waitqueue_head(&cam->smbus_wait); 506 mcam->plat_power_up = cafe_ctlr_power_up; 507 mcam->plat_power_down = cafe_ctlr_power_down; 508 mcam->dev = &pdev->dev; 509 snprintf(mcam->bus_info, sizeof(mcam->bus_info), "PCI:%s", pci_name(pdev)); 510 /* 511 * Vmalloc mode for buffers is traditional with this driver. 512 * We *might* be able to run DMA_contig, especially on a system 513 * with CMA in it. 514 */ 515 mcam->buffer_mode = B_vmalloc; 516 /* 517 * Get set up on the PCI bus. 518 */ 519 ret = pci_enable_device(pdev); 520 if (ret) 521 goto out_free; 522 pci_set_master(pdev); 523 524 ret = -EIO; 525 mcam->regs = pci_iomap(pdev, 0, 0); 526 if (!mcam->regs) { 527 printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n"); 528 goto out_disable; 529 } 530 mcam->regs_size = pci_resource_len(pdev, 0); 531 ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam); 532 if (ret) 533 goto out_iounmap; 534 535 /* 536 * Initialize the controller. 537 */ 538 cafe_ctlr_init(mcam); 539 540 /* 541 * Set up I2C/SMBUS communications. We have to drop the mutex here 542 * because the sensor could attach in this call chain, leading to 543 * unsightly deadlocks. 544 */ 545 ret = cafe_smbus_setup(cam); 546 if (ret) 547 goto out_pdown; 548 549 mcam->asd.match_type = V4L2_ASYNC_MATCH_I2C; 550 mcam->asd.match.i2c.adapter_id = i2c_adapter_id(cam->i2c_adapter); 551 mcam->asd.match.i2c.address = ov7670_info.addr; 552 553 ret = mccic_register(mcam); 554 if (ret) 555 goto out_smbus_shutdown; 556 557 clkdev_create(mcam->mclk, "xclk", "%d-%04x", 558 i2c_adapter_id(cam->i2c_adapter), ov7670_info.addr); 559 560 if (!IS_ERR(i2c_new_client_device(cam->i2c_adapter, &ov7670_info))) { 561 cam->registered = 1; 562 return 0; 563 } 564 565 mccic_shutdown(mcam); 566out_smbus_shutdown: 567 cafe_smbus_shutdown(cam); 568out_pdown: 569 cafe_ctlr_power_down(mcam); 570 free_irq(pdev->irq, cam); 571out_iounmap: 572 pci_iounmap(pdev, mcam->regs); 573out_disable: 574 pci_disable_device(pdev); 575out_free: 576 kfree(cam); 577out: 578 return ret; 579} 580 581 582/* 583 * Shut down an initialized device 584 */ 585static void cafe_shutdown(struct cafe_camera *cam) 586{ 587 mccic_shutdown(&cam->mcam); 588 cafe_smbus_shutdown(cam); 589 free_irq(cam->pdev->irq, cam); 590 pci_iounmap(cam->pdev, cam->mcam.regs); 591} 592 593 594static void cafe_pci_remove(struct pci_dev *pdev) 595{ 596 struct cafe_camera *cam = pci_get_drvdata(pdev); 597 598 if (cam == NULL) { 599 printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev); 600 return; 601 } 602 cafe_shutdown(cam); 603 kfree(cam); 604} 605 606 607/* 608 * Basic power management. 609 */ 610static int __maybe_unused cafe_pci_suspend(struct device *dev) 611{ 612 struct cafe_camera *cam = dev_get_drvdata(dev); 613 614 mccic_suspend(&cam->mcam); 615 return 0; 616} 617 618 619static int __maybe_unused cafe_pci_resume(struct device *dev) 620{ 621 struct cafe_camera *cam = dev_get_drvdata(dev); 622 623 cafe_ctlr_init(&cam->mcam); 624 return mccic_resume(&cam->mcam); 625} 626 627static const struct pci_device_id cafe_ids[] = { 628 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 629 PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) }, 630 { 0, } 631}; 632 633MODULE_DEVICE_TABLE(pci, cafe_ids); 634 635static SIMPLE_DEV_PM_OPS(cafe_pci_pm_ops, cafe_pci_suspend, cafe_pci_resume); 636 637static struct pci_driver cafe_pci_driver = { 638 .name = "cafe1000-ccic", 639 .id_table = cafe_ids, 640 .probe = cafe_pci_probe, 641 .remove = cafe_pci_remove, 642 .driver.pm = &cafe_pci_pm_ops, 643}; 644 645 646 647 648static int __init cafe_init(void) 649{ 650 int ret; 651 652 printk(KERN_NOTICE "Marvell M88ALP01 'CAFE' Camera Controller version %d\n", 653 CAFE_VERSION); 654 ret = pci_register_driver(&cafe_pci_driver); 655 if (ret) { 656 printk(KERN_ERR "Unable to register cafe_ccic driver\n"); 657 goto out; 658 } 659 ret = 0; 660 661out: 662 return ret; 663} 664 665 666static void __exit cafe_exit(void) 667{ 668 pci_unregister_driver(&cafe_pci_driver); 669} 670 671module_init(cafe_init); 672module_exit(cafe_exit); 673