root/drivers/media/pci/solo6x10/solo6x10-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. solo_set_time
  2. solo_timer_sync
  3. solo_isr
  4. free_solo_dev
  5. eeprom_store
  6. eeprom_show
  7. p2m_timeouts_show
  8. sdram_size_show
  9. tw28xx_show
  10. input_map_show
  11. p2m_timeout_store
  12. p2m_timeout_show
  13. intervals_show
  14. sdram_offsets_show
  15. sdram_show
  16. solo_device_release
  17. solo_sysfs_init
  18. solo_pci_probe
  19. solo_pci_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>
   4  *
   5  * Original author:
   6  * Ben Collins <bcollins@ubuntu.com>
   7  *
   8  * Additional work by:
   9  * John Brooks <john.brooks@bluecherry.net>
  10  */
  11 
  12 #include <linux/kernel.h>
  13 #include <linux/module.h>
  14 #include <linux/pci.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/videodev2.h>
  17 #include <linux/delay.h>
  18 #include <linux/sysfs.h>
  19 #include <linux/ktime.h>
  20 #include <linux/slab.h>
  21 
  22 #include "solo6x10.h"
  23 #include "solo6x10-tw28.h"
  24 
  25 MODULE_DESCRIPTION("Softlogic 6x10 MPEG4/H.264/G.723 CODEC V4L2/ALSA Driver");
  26 MODULE_AUTHOR("Bluecherry <maintainers@bluecherrydvr.com>");
  27 MODULE_VERSION(SOLO6X10_VERSION);
  28 MODULE_LICENSE("GPL");
  29 
  30 static unsigned video_nr = -1;
  31 module_param(video_nr, uint, 0644);
  32 MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect (default)");
  33 
  34 static int full_eeprom; /* default is only top 64B */
  35 module_param(full_eeprom, uint, 0644);
  36 MODULE_PARM_DESC(full_eeprom, "Allow access to full 128B EEPROM (dangerous)");
  37 
  38 
  39 static void solo_set_time(struct solo_dev *solo_dev)
  40 {
  41         struct timespec64 ts;
  42 
  43         ktime_get_ts64(&ts);
  44 
  45         /* no overflow because we use monotonic timestamps */
  46         solo_reg_write(solo_dev, SOLO_TIMER_SEC, (u32)ts.tv_sec);
  47         solo_reg_write(solo_dev, SOLO_TIMER_USEC, (u32)ts.tv_nsec / NSEC_PER_USEC);
  48 }
  49 
  50 static void solo_timer_sync(struct solo_dev *solo_dev)
  51 {
  52         u32 sec, usec;
  53         struct timespec64 ts;
  54         long diff;
  55 
  56         if (solo_dev->type != SOLO_DEV_6110)
  57                 return;
  58 
  59         if (++solo_dev->time_sync < 60)
  60                 return;
  61 
  62         solo_dev->time_sync = 0;
  63 
  64         sec = solo_reg_read(solo_dev, SOLO_TIMER_SEC);
  65         usec = solo_reg_read(solo_dev, SOLO_TIMER_USEC);
  66 
  67         ktime_get_ts64(&ts);
  68 
  69         diff = (s32)ts.tv_sec - (s32)sec;
  70         diff = (diff * 1000000)
  71                 + ((s32)(ts.tv_nsec / NSEC_PER_USEC) - (s32)usec);
  72 
  73         if (diff > 1000 || diff < -1000) {
  74                 solo_set_time(solo_dev);
  75         } else if (diff) {
  76                 long usec_lsb = solo_dev->usec_lsb;
  77 
  78                 usec_lsb -= diff / 4;
  79                 if (usec_lsb < 0)
  80                         usec_lsb = 0;
  81                 else if (usec_lsb > 255)
  82                         usec_lsb = 255;
  83 
  84                 solo_dev->usec_lsb = usec_lsb;
  85                 solo_reg_write(solo_dev, SOLO_TIMER_USEC_LSB,
  86                                solo_dev->usec_lsb);
  87         }
  88 }
  89 
  90 static irqreturn_t solo_isr(int irq, void *data)
  91 {
  92         struct solo_dev *solo_dev = data;
  93         u32 status;
  94         int i;
  95 
  96         status = solo_reg_read(solo_dev, SOLO_IRQ_STAT);
  97         if (!status)
  98                 return IRQ_NONE;
  99 
 100         /* Acknowledge all interrupts immediately */
 101         solo_reg_write(solo_dev, SOLO_IRQ_STAT, status);
 102 
 103         if (status & SOLO_IRQ_PCI_ERR)
 104                 solo_p2m_error_isr(solo_dev);
 105 
 106         for (i = 0; i < SOLO_NR_P2M; i++)
 107                 if (status & SOLO_IRQ_P2M(i))
 108                         solo_p2m_isr(solo_dev, i);
 109 
 110         if (status & SOLO_IRQ_IIC)
 111                 solo_i2c_isr(solo_dev);
 112 
 113         if (status & SOLO_IRQ_VIDEO_IN) {
 114                 solo_video_in_isr(solo_dev);
 115                 solo_timer_sync(solo_dev);
 116         }
 117 
 118         if (status & SOLO_IRQ_ENCODER)
 119                 solo_enc_v4l2_isr(solo_dev);
 120 
 121         if (status & SOLO_IRQ_G723)
 122                 solo_g723_isr(solo_dev);
 123 
 124         return IRQ_HANDLED;
 125 }
 126 
 127 static void free_solo_dev(struct solo_dev *solo_dev)
 128 {
 129         struct pci_dev *pdev = solo_dev->pdev;
 130 
 131         if (solo_dev->dev.parent)
 132                 device_unregister(&solo_dev->dev);
 133 
 134         if (solo_dev->reg_base) {
 135                 /* Bring down the sub-devices first */
 136                 solo_g723_exit(solo_dev);
 137                 solo_enc_v4l2_exit(solo_dev);
 138                 solo_enc_exit(solo_dev);
 139                 solo_v4l2_exit(solo_dev);
 140                 solo_disp_exit(solo_dev);
 141                 solo_gpio_exit(solo_dev);
 142                 solo_p2m_exit(solo_dev);
 143                 solo_i2c_exit(solo_dev);
 144 
 145                 /* Now cleanup the PCI device */
 146                 solo_irq_off(solo_dev, ~0);
 147                 free_irq(pdev->irq, solo_dev);
 148                 pci_iounmap(pdev, solo_dev->reg_base);
 149         }
 150 
 151         pci_release_regions(pdev);
 152         pci_disable_device(pdev);
 153         v4l2_device_unregister(&solo_dev->v4l2_dev);
 154         pci_set_drvdata(pdev, NULL);
 155 
 156         kfree(solo_dev);
 157 }
 158 
 159 static ssize_t eeprom_store(struct device *dev, struct device_attribute *attr,
 160                             const char *buf, size_t count)
 161 {
 162         struct solo_dev *solo_dev =
 163                 container_of(dev, struct solo_dev, dev);
 164         u16 *p = (u16 *)buf;
 165         int i;
 166 
 167         if (count & 0x1)
 168                 dev_warn(dev, "EEPROM Write not aligned (truncating)\n");
 169 
 170         if (!full_eeprom && count > 64) {
 171                 dev_warn(dev, "EEPROM Write truncated to 64 bytes\n");
 172                 count = 64;
 173         } else if (full_eeprom && count > 128) {
 174                 dev_warn(dev, "EEPROM Write truncated to 128 bytes\n");
 175                 count = 128;
 176         }
 177 
 178         solo_eeprom_ewen(solo_dev, 1);
 179 
 180         for (i = full_eeprom ? 0 : 32; i < min((int)(full_eeprom ? 64 : 32),
 181                                                (int)(count / 2)); i++)
 182                 solo_eeprom_write(solo_dev, i, cpu_to_be16(p[i]));
 183 
 184         solo_eeprom_ewen(solo_dev, 0);
 185 
 186         return count;
 187 }
 188 
 189 static ssize_t eeprom_show(struct device *dev, struct device_attribute *attr,
 190                            char *buf)
 191 {
 192         struct solo_dev *solo_dev =
 193                 container_of(dev, struct solo_dev, dev);
 194         u16 *p = (u16 *)buf;
 195         int count = (full_eeprom ? 128 : 64);
 196         int i;
 197 
 198         for (i = (full_eeprom ? 0 : 32); i < (count / 2); i++)
 199                 p[i] = be16_to_cpu(solo_eeprom_read(solo_dev, i));
 200 
 201         return count;
 202 }
 203 
 204 static ssize_t p2m_timeouts_show(struct device *dev,
 205                                  struct device_attribute *attr,
 206                                  char *buf)
 207 {
 208         struct solo_dev *solo_dev =
 209                 container_of(dev, struct solo_dev, dev);
 210 
 211         return sprintf(buf, "%d\n", solo_dev->p2m_timeouts);
 212 }
 213 
 214 static ssize_t sdram_size_show(struct device *dev,
 215                                struct device_attribute *attr,
 216                                char *buf)
 217 {
 218         struct solo_dev *solo_dev =
 219                 container_of(dev, struct solo_dev, dev);
 220 
 221         return sprintf(buf, "%dMegs\n", solo_dev->sdram_size >> 20);
 222 }
 223 
 224 static ssize_t tw28xx_show(struct device *dev,
 225                            struct device_attribute *attr,
 226                            char *buf)
 227 {
 228         struct solo_dev *solo_dev =
 229                 container_of(dev, struct solo_dev, dev);
 230 
 231         return sprintf(buf, "tw2815[%d] tw2864[%d] tw2865[%d]\n",
 232                        hweight32(solo_dev->tw2815),
 233                        hweight32(solo_dev->tw2864),
 234                        hweight32(solo_dev->tw2865));
 235 }
 236 
 237 static ssize_t input_map_show(struct device *dev,
 238                               struct device_attribute *attr,
 239                               char *buf)
 240 {
 241         struct solo_dev *solo_dev =
 242                 container_of(dev, struct solo_dev, dev);
 243         unsigned int val;
 244         char *out = buf;
 245 
 246         val = solo_reg_read(solo_dev, SOLO_VI_CH_SWITCH_0);
 247         out += sprintf(out, "Channel 0   => Input %d\n", val & 0x1f);
 248         out += sprintf(out, "Channel 1   => Input %d\n", (val >> 5) & 0x1f);
 249         out += sprintf(out, "Channel 2   => Input %d\n", (val >> 10) & 0x1f);
 250         out += sprintf(out, "Channel 3   => Input %d\n", (val >> 15) & 0x1f);
 251         out += sprintf(out, "Channel 4   => Input %d\n", (val >> 20) & 0x1f);
 252         out += sprintf(out, "Channel 5   => Input %d\n", (val >> 25) & 0x1f);
 253 
 254         val = solo_reg_read(solo_dev, SOLO_VI_CH_SWITCH_1);
 255         out += sprintf(out, "Channel 6   => Input %d\n", val & 0x1f);
 256         out += sprintf(out, "Channel 7   => Input %d\n", (val >> 5) & 0x1f);
 257         out += sprintf(out, "Channel 8   => Input %d\n", (val >> 10) & 0x1f);
 258         out += sprintf(out, "Channel 9   => Input %d\n", (val >> 15) & 0x1f);
 259         out += sprintf(out, "Channel 10  => Input %d\n", (val >> 20) & 0x1f);
 260         out += sprintf(out, "Channel 11  => Input %d\n", (val >> 25) & 0x1f);
 261 
 262         val = solo_reg_read(solo_dev, SOLO_VI_CH_SWITCH_2);
 263         out += sprintf(out, "Channel 12  => Input %d\n", val & 0x1f);
 264         out += sprintf(out, "Channel 13  => Input %d\n", (val >> 5) & 0x1f);
 265         out += sprintf(out, "Channel 14  => Input %d\n", (val >> 10) & 0x1f);
 266         out += sprintf(out, "Channel 15  => Input %d\n", (val >> 15) & 0x1f);
 267         out += sprintf(out, "Spot Output => Input %d\n", (val >> 20) & 0x1f);
 268 
 269         return out - buf;
 270 }
 271 
 272 static ssize_t p2m_timeout_store(struct device *dev,
 273                                  struct device_attribute *attr,
 274                                  const char *buf, size_t count)
 275 {
 276         struct solo_dev *solo_dev =
 277                 container_of(dev, struct solo_dev, dev);
 278         unsigned long ms;
 279         int ret = kstrtoul(buf, 10, &ms);
 280 
 281         if (ret < 0 || ms > 200)
 282                 return -EINVAL;
 283         solo_dev->p2m_jiffies = msecs_to_jiffies(ms);
 284 
 285         return count;
 286 }
 287 
 288 static ssize_t p2m_timeout_show(struct device *dev,
 289                                 struct device_attribute *attr,
 290                                 char *buf)
 291 {
 292         struct solo_dev *solo_dev =
 293                 container_of(dev, struct solo_dev, dev);
 294 
 295         return sprintf(buf, "%ums\n", jiffies_to_msecs(solo_dev->p2m_jiffies));
 296 }
 297 
 298 static ssize_t intervals_show(struct device *dev,
 299                               struct device_attribute *attr,
 300                               char *buf)
 301 {
 302         struct solo_dev *solo_dev =
 303                 container_of(dev, struct solo_dev, dev);
 304         char *out = buf;
 305         int fps = solo_dev->fps;
 306         int i;
 307 
 308         for (i = 0; i < solo_dev->nr_chans; i++) {
 309                 out += sprintf(out, "Channel %d: %d/%d (0x%08x)\n",
 310                                i, solo_dev->v4l2_enc[i]->interval, fps,
 311                                solo_reg_read(solo_dev, SOLO_CAP_CH_INTV(i)));
 312         }
 313 
 314         return out - buf;
 315 }
 316 
 317 static ssize_t sdram_offsets_show(struct device *dev,
 318                                   struct device_attribute *attr,
 319                                   char *buf)
 320 {
 321         struct solo_dev *solo_dev =
 322                 container_of(dev, struct solo_dev, dev);
 323         char *out = buf;
 324 
 325         out += sprintf(out, "DISP: 0x%08x @ 0x%08x\n",
 326                        SOLO_DISP_EXT_ADDR,
 327                        SOLO_DISP_EXT_SIZE);
 328 
 329         out += sprintf(out, "EOSD: 0x%08x @ 0x%08x (0x%08x * %d)\n",
 330                        SOLO_EOSD_EXT_ADDR,
 331                        SOLO_EOSD_EXT_AREA(solo_dev),
 332                        SOLO_EOSD_EXT_SIZE(solo_dev),
 333                        SOLO_EOSD_EXT_AREA(solo_dev) /
 334                        SOLO_EOSD_EXT_SIZE(solo_dev));
 335 
 336         out += sprintf(out, "MOTI: 0x%08x @ 0x%08x\n",
 337                        SOLO_MOTION_EXT_ADDR(solo_dev),
 338                        SOLO_MOTION_EXT_SIZE);
 339 
 340         out += sprintf(out, "G723: 0x%08x @ 0x%08x\n",
 341                        SOLO_G723_EXT_ADDR(solo_dev),
 342                        SOLO_G723_EXT_SIZE);
 343 
 344         out += sprintf(out, "CAPT: 0x%08x @ 0x%08x (0x%08x * %d)\n",
 345                        SOLO_CAP_EXT_ADDR(solo_dev),
 346                        SOLO_CAP_EXT_SIZE(solo_dev),
 347                        SOLO_CAP_PAGE_SIZE,
 348                        SOLO_CAP_EXT_SIZE(solo_dev) / SOLO_CAP_PAGE_SIZE);
 349 
 350         out += sprintf(out, "EREF: 0x%08x @ 0x%08x (0x%08x * %d)\n",
 351                        SOLO_EREF_EXT_ADDR(solo_dev),
 352                        SOLO_EREF_EXT_AREA(solo_dev),
 353                        SOLO_EREF_EXT_SIZE,
 354                        SOLO_EREF_EXT_AREA(solo_dev) / SOLO_EREF_EXT_SIZE);
 355 
 356         out += sprintf(out, "MPEG: 0x%08x @ 0x%08x\n",
 357                        SOLO_MP4E_EXT_ADDR(solo_dev),
 358                        SOLO_MP4E_EXT_SIZE(solo_dev));
 359 
 360         out += sprintf(out, "JPEG: 0x%08x @ 0x%08x\n",
 361                        SOLO_JPEG_EXT_ADDR(solo_dev),
 362                        SOLO_JPEG_EXT_SIZE(solo_dev));
 363 
 364         return out - buf;
 365 }
 366 
 367 static ssize_t sdram_show(struct file *file, struct kobject *kobj,
 368                           struct bin_attribute *a, char *buf,
 369                           loff_t off, size_t count)
 370 {
 371         struct device *dev = container_of(kobj, struct device, kobj);
 372         struct solo_dev *solo_dev =
 373                 container_of(dev, struct solo_dev, dev);
 374         const int size = solo_dev->sdram_size;
 375 
 376         if (off >= size)
 377                 return 0;
 378 
 379         if (off + count > size)
 380                 count = size - off;
 381 
 382         if (solo_p2m_dma(solo_dev, 0, buf, off, count, 0, 0))
 383                 return -EIO;
 384 
 385         return count;
 386 }
 387 
 388 static const struct device_attribute solo_dev_attrs[] = {
 389         __ATTR(eeprom, 0640, eeprom_show, eeprom_store),
 390         __ATTR(p2m_timeout, 0644, p2m_timeout_show, p2m_timeout_store),
 391         __ATTR_RO(p2m_timeouts),
 392         __ATTR_RO(sdram_size),
 393         __ATTR_RO(tw28xx),
 394         __ATTR_RO(input_map),
 395         __ATTR_RO(intervals),
 396         __ATTR_RO(sdram_offsets),
 397 };
 398 
 399 static void solo_device_release(struct device *dev)
 400 {
 401         /* Do nothing */
 402 }
 403 
 404 static int solo_sysfs_init(struct solo_dev *solo_dev)
 405 {
 406         struct bin_attribute *sdram_attr = &solo_dev->sdram_attr;
 407         struct device *dev = &solo_dev->dev;
 408         const char *driver;
 409         int i;
 410 
 411         if (solo_dev->type == SOLO_DEV_6110)
 412                 driver = "solo6110";
 413         else
 414                 driver = "solo6010";
 415 
 416         dev->release = solo_device_release;
 417         dev->parent = &solo_dev->pdev->dev;
 418         set_dev_node(dev, dev_to_node(&solo_dev->pdev->dev));
 419         dev_set_name(dev, "%s-%d-%d", driver, solo_dev->vfd->num,
 420                      solo_dev->nr_chans);
 421 
 422         if (device_register(dev)) {
 423                 dev->parent = NULL;
 424                 return -ENOMEM;
 425         }
 426 
 427         for (i = 0; i < ARRAY_SIZE(solo_dev_attrs); i++) {
 428                 if (device_create_file(dev, &solo_dev_attrs[i])) {
 429                         device_unregister(dev);
 430                         return -ENOMEM;
 431                 }
 432         }
 433 
 434         sysfs_attr_init(&sdram_attr->attr);
 435         sdram_attr->attr.name = "sdram";
 436         sdram_attr->attr.mode = 0440;
 437         sdram_attr->read = sdram_show;
 438         sdram_attr->size = solo_dev->sdram_size;
 439 
 440         if (device_create_bin_file(dev, sdram_attr)) {
 441                 device_unregister(dev);
 442                 return -ENOMEM;
 443         }
 444 
 445         return 0;
 446 }
 447 
 448 static int solo_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 449 {
 450         struct solo_dev *solo_dev;
 451         int ret;
 452         u8 chip_id;
 453 
 454         solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL);
 455         if (solo_dev == NULL)
 456                 return -ENOMEM;
 457 
 458         if (id->driver_data == SOLO_DEV_6010)
 459                 dev_info(&pdev->dev, "Probing Softlogic 6010\n");
 460         else
 461                 dev_info(&pdev->dev, "Probing Softlogic 6110\n");
 462 
 463         solo_dev->type = id->driver_data;
 464         solo_dev->pdev = pdev;
 465         ret = v4l2_device_register(&pdev->dev, &solo_dev->v4l2_dev);
 466         if (ret)
 467                 goto fail_probe;
 468 
 469         /* Only for during init */
 470         solo_dev->p2m_jiffies = msecs_to_jiffies(100);
 471 
 472         ret = pci_enable_device(pdev);
 473         if (ret)
 474                 goto fail_probe;
 475 
 476         pci_set_master(pdev);
 477 
 478         /* RETRY/TRDY Timeout disabled */
 479         pci_write_config_byte(pdev, 0x40, 0x00);
 480         pci_write_config_byte(pdev, 0x41, 0x00);
 481 
 482         ret = pci_request_regions(pdev, SOLO6X10_NAME);
 483         if (ret)
 484                 goto fail_probe;
 485 
 486         solo_dev->reg_base = pci_ioremap_bar(pdev, 0);
 487         if (solo_dev->reg_base == NULL) {
 488                 ret = -ENOMEM;
 489                 goto fail_probe;
 490         }
 491 
 492         chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) &
 493                                 SOLO_CHIP_ID_MASK;
 494         switch (chip_id) {
 495         case 7:
 496                 solo_dev->nr_chans = 16;
 497                 solo_dev->nr_ext = 5;
 498                 break;
 499         case 6:
 500                 solo_dev->nr_chans = 8;
 501                 solo_dev->nr_ext = 2;
 502                 break;
 503         default:
 504                 dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, assuming 4 ch\n",
 505                          chip_id);
 506                 /* fall through */
 507         case 5:
 508                 solo_dev->nr_chans = 4;
 509                 solo_dev->nr_ext = 1;
 510         }
 511 
 512         /* Disable all interrupts to start */
 513         solo_irq_off(solo_dev, ~0);
 514 
 515         /* Initial global settings */
 516         if (solo_dev->type == SOLO_DEV_6010) {
 517                 solo_dev->clock_mhz = 108;
 518                 solo_dev->sys_config = SOLO_SYS_CFG_SDRAM64BIT
 519                         | SOLO_SYS_CFG_INPUTDIV(25)
 520                         | SOLO_SYS_CFG_FEEDBACKDIV(solo_dev->clock_mhz * 2 - 2)
 521                         | SOLO_SYS_CFG_OUTDIV(3);
 522                 solo_reg_write(solo_dev, SOLO_SYS_CFG, solo_dev->sys_config);
 523         } else {
 524                 u32 divq, divf;
 525 
 526                 solo_dev->clock_mhz = 135;
 527 
 528                 if (solo_dev->clock_mhz < 125) {
 529                         divq = 3;
 530                         divf = (solo_dev->clock_mhz * 4) / 3 - 1;
 531                 } else {
 532                         divq = 2;
 533                         divf = (solo_dev->clock_mhz * 2) / 3 - 1;
 534                 }
 535 
 536                 solo_reg_write(solo_dev, SOLO_PLL_CONFIG,
 537                                (1 << 20) | /* PLL_RANGE */
 538                                (8 << 15) | /* PLL_DIVR  */
 539                                (divq << 12) |
 540                                (divf <<  4) |
 541                                (1 <<  1)   /* PLL_FSEN */);
 542 
 543                 solo_dev->sys_config = SOLO_SYS_CFG_SDRAM64BIT;
 544         }
 545 
 546         solo_reg_write(solo_dev, SOLO_SYS_CFG, solo_dev->sys_config);
 547         solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM,
 548                        solo_dev->clock_mhz - 1);
 549 
 550         /* PLL locking time of 1ms */
 551         mdelay(1);
 552 
 553         ret = request_irq(pdev->irq, solo_isr, IRQF_SHARED, SOLO6X10_NAME,
 554                           solo_dev);
 555         if (ret)
 556                 goto fail_probe;
 557 
 558         /* Handle this from the start */
 559         solo_irq_on(solo_dev, SOLO_IRQ_PCI_ERR);
 560 
 561         ret = solo_i2c_init(solo_dev);
 562         if (ret)
 563                 goto fail_probe;
 564 
 565         /* Setup the DMA engine */
 566         solo_reg_write(solo_dev, SOLO_DMA_CTRL,
 567                        SOLO_DMA_CTRL_REFRESH_CYCLE(1) |
 568                        SOLO_DMA_CTRL_SDRAM_SIZE(2) |
 569                        SOLO_DMA_CTRL_SDRAM_CLK_INVERT |
 570                        SOLO_DMA_CTRL_READ_CLK_SELECT |
 571                        SOLO_DMA_CTRL_LATENCY(1));
 572 
 573         /* Undocumented crap */
 574         solo_reg_write(solo_dev, SOLO_DMA_CTRL1,
 575                        solo_dev->type == SOLO_DEV_6010 ? 0x100 : 0x300);
 576 
 577         if (solo_dev->type != SOLO_DEV_6010) {
 578                 solo_dev->usec_lsb = 0x3f;
 579                 solo_set_time(solo_dev);
 580         }
 581 
 582         /* Disable watchdog */
 583         solo_reg_write(solo_dev, SOLO_WATCHDOG, 0);
 584 
 585         /* Initialize sub components */
 586 
 587         ret = solo_p2m_init(solo_dev);
 588         if (ret)
 589                 goto fail_probe;
 590 
 591         ret = solo_disp_init(solo_dev);
 592         if (ret)
 593                 goto fail_probe;
 594 
 595         ret = solo_gpio_init(solo_dev);
 596         if (ret)
 597                 goto fail_probe;
 598 
 599         ret = solo_tw28_init(solo_dev);
 600         if (ret)
 601                 goto fail_probe;
 602 
 603         ret = solo_v4l2_init(solo_dev, video_nr);
 604         if (ret)
 605                 goto fail_probe;
 606 
 607         ret = solo_enc_init(solo_dev);
 608         if (ret)
 609                 goto fail_probe;
 610 
 611         ret = solo_enc_v4l2_init(solo_dev, video_nr);
 612         if (ret)
 613                 goto fail_probe;
 614 
 615         ret = solo_g723_init(solo_dev);
 616         if (ret)
 617                 goto fail_probe;
 618 
 619         ret = solo_sysfs_init(solo_dev);
 620         if (ret)
 621                 goto fail_probe;
 622 
 623         /* Now that init is over, set this lower */
 624         solo_dev->p2m_jiffies = msecs_to_jiffies(20);
 625 
 626         return 0;
 627 
 628 fail_probe:
 629         free_solo_dev(solo_dev);
 630         return ret;
 631 }
 632 
 633 static void solo_pci_remove(struct pci_dev *pdev)
 634 {
 635         struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
 636         struct solo_dev *solo_dev = container_of(v4l2_dev, struct solo_dev, v4l2_dev);
 637 
 638         free_solo_dev(solo_dev);
 639 }
 640 
 641 static const struct pci_device_id solo_id_table[] = {
 642         /* 6010 based cards */
 643         { PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010),
 644           .driver_data = SOLO_DEV_6010 },
 645         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4),
 646           .driver_data = SOLO_DEV_6010 },
 647         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9),
 648           .driver_data = SOLO_DEV_6010 },
 649         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16),
 650           .driver_data = SOLO_DEV_6010 },
 651         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_4),
 652           .driver_data = SOLO_DEV_6010 },
 653         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_9),
 654           .driver_data = SOLO_DEV_6010 },
 655         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_16),
 656           .driver_data = SOLO_DEV_6010 },
 657         /* 6110 based cards */
 658         { PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6110),
 659           .driver_data = SOLO_DEV_6110 },
 660         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_4),
 661           .driver_data = SOLO_DEV_6110 },
 662         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_8),
 663           .driver_data = SOLO_DEV_6110 },
 664         { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_16),
 665           .driver_data = SOLO_DEV_6110 },
 666         {0,}
 667 };
 668 
 669 MODULE_DEVICE_TABLE(pci, solo_id_table);
 670 
 671 static struct pci_driver solo_pci_driver = {
 672         .name = SOLO6X10_NAME,
 673         .id_table = solo_id_table,
 674         .probe = solo_pci_probe,
 675         .remove = solo_pci_remove,
 676 };
 677 
 678 module_pci_driver(solo_pci_driver);

/* [<][>][^][v][top][bottom][index][help] */