Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  cobalt driver initialization and card probing
0004  *
0005  *  Derived from cx18-driver.c
0006  *
0007  *  Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates.
0008  *  All rights reserved.
0009  */
0010 
0011 #include <linux/delay.h>
0012 #include <media/i2c/adv7604.h>
0013 #include <media/i2c/adv7842.h>
0014 #include <media/i2c/adv7511.h>
0015 #include <media/v4l2-event.h>
0016 #include <media/v4l2-ctrls.h>
0017 
0018 #include "cobalt-driver.h"
0019 #include "cobalt-irq.h"
0020 #include "cobalt-i2c.h"
0021 #include "cobalt-v4l2.h"
0022 #include "cobalt-flash.h"
0023 #include "cobalt-alsa.h"
0024 #include "cobalt-omnitek.h"
0025 
0026 /* add your revision and whatnot here */
0027 static const struct pci_device_id cobalt_pci_tbl[] = {
0028     {PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_COBALT,
0029      PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
0030     {0,}
0031 };
0032 
0033 MODULE_DEVICE_TABLE(pci, cobalt_pci_tbl);
0034 
0035 static atomic_t cobalt_instance = ATOMIC_INIT(0);
0036 
0037 int cobalt_debug;
0038 module_param_named(debug, cobalt_debug, int, 0644);
0039 MODULE_PARM_DESC(debug, "Debug level. Default: 0\n");
0040 
0041 int cobalt_ignore_err;
0042 module_param_named(ignore_err, cobalt_ignore_err, int, 0644);
0043 MODULE_PARM_DESC(ignore_err,
0044     "If set then ignore missing i2c adapters/receivers. Default: 0\n");
0045 
0046 MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com> & Morten Hestnes");
0047 MODULE_DESCRIPTION("cobalt driver");
0048 MODULE_LICENSE("GPL");
0049 
0050 static u8 edid[256] = {
0051     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0052     0x50, 0x21, 0x32, 0x27, 0x00, 0x00, 0x00, 0x00,
0053     0x22, 0x1a, 0x01, 0x03, 0x80, 0x30, 0x1b, 0x78,
0054     0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26,
0055     0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59,
0056     0x45, 0x59, 0x61, 0x59, 0x81, 0x99, 0x01, 0x01,
0057     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a,
0058     0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
0059     0x45, 0x00, 0xe0, 0x0e, 0x11, 0x00, 0x00, 0x1e,
0060     0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18,
0061     0x5e, 0x11, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20,
0062     0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x63,
0063     0x6f, 0x62, 0x61, 0x6c, 0x74, 0x0a, 0x20, 0x20,
0064     0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10,
0065     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0066     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9d,
0067 
0068     0x02, 0x03, 0x1f, 0xf1, 0x4a, 0x10, 0x1f, 0x04,
0069     0x13, 0x22, 0x21, 0x20, 0x02, 0x11, 0x01, 0x23,
0070     0x09, 0x07, 0x07, 0x68, 0x03, 0x0c, 0x00, 0x10,
0071     0x00, 0x00, 0x22, 0x0f, 0xe2, 0x00, 0xca, 0x00,
0072     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0073     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0074     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0075     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0076     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0077     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0078     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0079     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0080     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0081     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0082     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0083     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
0084 };
0085 
0086 static void cobalt_set_interrupt(struct cobalt *cobalt, bool enable)
0087 {
0088     if (enable) {
0089         unsigned irqs = COBALT_SYSSTAT_VI0_INT1_MSK |
0090                 COBALT_SYSSTAT_VI1_INT1_MSK |
0091                 COBALT_SYSSTAT_VI2_INT1_MSK |
0092                 COBALT_SYSSTAT_VI3_INT1_MSK |
0093                 COBALT_SYSSTAT_VI0_INT2_MSK |
0094                 COBALT_SYSSTAT_VI1_INT2_MSK |
0095                 COBALT_SYSSTAT_VI2_INT2_MSK |
0096                 COBALT_SYSSTAT_VI3_INT2_MSK |
0097                 COBALT_SYSSTAT_VI0_LOST_DATA_MSK |
0098                 COBALT_SYSSTAT_VI1_LOST_DATA_MSK |
0099                 COBALT_SYSSTAT_VI2_LOST_DATA_MSK |
0100                 COBALT_SYSSTAT_VI3_LOST_DATA_MSK |
0101                 COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK;
0102 
0103         if (cobalt->have_hsma_rx)
0104             irqs |= COBALT_SYSSTAT_VIHSMA_INT1_MSK |
0105                 COBALT_SYSSTAT_VIHSMA_INT2_MSK |
0106                 COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK;
0107 
0108         if (cobalt->have_hsma_tx)
0109             irqs |= COBALT_SYSSTAT_VOHSMA_INT1_MSK |
0110                 COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK |
0111                 COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK;
0112         /* Clear any existing interrupts */
0113         cobalt_write_bar1(cobalt, COBALT_SYS_STAT_EDGE, 0xffffffff);
0114         /* PIO Core interrupt mask register.
0115            Enable ADV7604 INT1 interrupts */
0116         cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, irqs);
0117     } else {
0118         /* Disable all ADV7604 interrupts */
0119         cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, 0);
0120     }
0121 }
0122 
0123 static unsigned cobalt_get_sd_nr(struct v4l2_subdev *sd)
0124 {
0125     struct cobalt *cobalt = to_cobalt(sd->v4l2_dev);
0126     unsigned i;
0127 
0128     for (i = 0; i < COBALT_NUM_NODES; i++)
0129         if (sd == cobalt->streams[i].sd)
0130             return i;
0131     cobalt_err("Invalid adv7604 subdev pointer!\n");
0132     return 0;
0133 }
0134 
0135 static void cobalt_notify(struct v4l2_subdev *sd,
0136               unsigned int notification, void *arg)
0137 {
0138     struct cobalt *cobalt = to_cobalt(sd->v4l2_dev);
0139     unsigned sd_nr = cobalt_get_sd_nr(sd);
0140     struct cobalt_stream *s = &cobalt->streams[sd_nr];
0141     bool hotplug = arg ? *((int *)arg) : false;
0142 
0143     if (s->is_output)
0144         return;
0145 
0146     switch (notification) {
0147     case ADV76XX_HOTPLUG:
0148         cobalt_s_bit_sysctrl(cobalt,
0149             COBALT_SYS_CTRL_HPD_TO_CONNECTOR_BIT(sd_nr), hotplug);
0150         cobalt_dbg(1, "Set hotplug for adv %d to %d\n", sd_nr, hotplug);
0151         break;
0152     case V4L2_DEVICE_NOTIFY_EVENT:
0153         cobalt_dbg(1, "Format changed for adv %d\n", sd_nr);
0154         v4l2_event_queue(&s->vdev, arg);
0155         break;
0156     default:
0157         break;
0158     }
0159 }
0160 
0161 static int get_payload_size(u16 code)
0162 {
0163     switch (code) {
0164     case 0: return 128;
0165     case 1: return 256;
0166     case 2: return 512;
0167     case 3: return 1024;
0168     case 4: return 2048;
0169     case 5: return 4096;
0170     default: return 0;
0171     }
0172     return 0;
0173 }
0174 
0175 static const char *get_link_speed(u16 stat)
0176 {
0177     switch (stat & PCI_EXP_LNKSTA_CLS) {
0178     case 1: return "2.5 Gbit/s";
0179     case 2: return "5 Gbit/s";
0180     case 3: return "10 Gbit/s";
0181     }
0182     return "Unknown speed";
0183 }
0184 
0185 void cobalt_pcie_status_show(struct cobalt *cobalt)
0186 {
0187     struct pci_dev *pci_dev = cobalt->pci_dev;
0188     struct pci_dev *pci_bus_dev = cobalt->pci_dev->bus->self;
0189     u32 capa;
0190     u16 stat, ctrl;
0191 
0192     if (!pci_is_pcie(pci_dev) || !pci_is_pcie(pci_bus_dev))
0193         return;
0194 
0195     /* Device */
0196     pcie_capability_read_dword(pci_dev, PCI_EXP_DEVCAP, &capa);
0197     pcie_capability_read_word(pci_dev, PCI_EXP_DEVCTL, &ctrl);
0198     pcie_capability_read_word(pci_dev, PCI_EXP_DEVSTA, &stat);
0199     cobalt_info("PCIe device capability 0x%08x: Max payload %d\n",
0200             capa, get_payload_size(capa & PCI_EXP_DEVCAP_PAYLOAD));
0201     cobalt_info("PCIe device control 0x%04x: Max payload %d. Max read request %d\n",
0202             ctrl,
0203             get_payload_size((ctrl & PCI_EXP_DEVCTL_PAYLOAD) >> 5),
0204             get_payload_size((ctrl & PCI_EXP_DEVCTL_READRQ) >> 12));
0205     cobalt_info("PCIe device status 0x%04x\n", stat);
0206 
0207     /* Link */
0208     pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &capa);
0209     pcie_capability_read_word(pci_dev, PCI_EXP_LNKCTL, &ctrl);
0210     pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &stat);
0211     cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n",
0212             capa, get_link_speed(capa),
0213             (capa & PCI_EXP_LNKCAP_MLW) >> 4);
0214     cobalt_info("PCIe link control 0x%04x\n", ctrl);
0215     cobalt_info("PCIe link status 0x%04x: %s per lane and %u lanes\n",
0216             stat, get_link_speed(stat),
0217             (stat & PCI_EXP_LNKSTA_NLW) >> 4);
0218 
0219     /* Bus */
0220     pcie_capability_read_dword(pci_bus_dev, PCI_EXP_LNKCAP, &capa);
0221     cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n",
0222             capa, get_link_speed(capa),
0223             (capa & PCI_EXP_LNKCAP_MLW) >> 4);
0224 
0225     /* Slot */
0226     pcie_capability_read_dword(pci_dev, PCI_EXP_SLTCAP, &capa);
0227     pcie_capability_read_word(pci_dev, PCI_EXP_SLTCTL, &ctrl);
0228     pcie_capability_read_word(pci_dev, PCI_EXP_SLTSTA, &stat);
0229     cobalt_info("PCIe slot capability 0x%08x\n", capa);
0230     cobalt_info("PCIe slot control 0x%04x\n", ctrl);
0231     cobalt_info("PCIe slot status 0x%04x\n", stat);
0232 }
0233 
0234 static unsigned pcie_link_get_lanes(struct cobalt *cobalt)
0235 {
0236     struct pci_dev *pci_dev = cobalt->pci_dev;
0237     u16 link;
0238 
0239     if (!pci_is_pcie(pci_dev))
0240         return 0;
0241     pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &link);
0242     return (link & PCI_EXP_LNKSTA_NLW) >> 4;
0243 }
0244 
0245 static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt)
0246 {
0247     struct pci_dev *pci_dev = cobalt->pci_dev->bus->self;
0248     u32 link;
0249 
0250     if (!pci_is_pcie(pci_dev))
0251         return 0;
0252     pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &link);
0253     return (link & PCI_EXP_LNKCAP_MLW) >> 4;
0254 }
0255 
0256 static void msi_config_show(struct cobalt *cobalt, struct pci_dev *pci_dev)
0257 {
0258     u16 ctrl, data;
0259     u32 adrs_l, adrs_h;
0260 
0261     pci_read_config_word(pci_dev, 0x52, &ctrl);
0262     cobalt_info("MSI %s\n", ctrl & 1 ? "enable" : "disable");
0263     cobalt_info("MSI multiple message: Capable %u. Enable %u\n",
0264             (1 << ((ctrl >> 1) & 7)), (1 << ((ctrl >> 4) & 7)));
0265     if (ctrl & 0x80)
0266         cobalt_info("MSI: 64-bit address capable\n");
0267     pci_read_config_dword(pci_dev, 0x54, &adrs_l);
0268     pci_read_config_dword(pci_dev, 0x58, &adrs_h);
0269     pci_read_config_word(pci_dev, 0x5c, &data);
0270     if (ctrl & 0x80)
0271         cobalt_info("MSI: Address 0x%08x%08x. Data 0x%04x\n",
0272                 adrs_h, adrs_l, data);
0273     else
0274         cobalt_info("MSI: Address 0x%08x. Data 0x%04x\n",
0275                 adrs_l, data);
0276 }
0277 
0278 static void cobalt_pci_iounmap(struct cobalt *cobalt, struct pci_dev *pci_dev)
0279 {
0280     if (cobalt->bar0) {
0281         pci_iounmap(pci_dev, cobalt->bar0);
0282         cobalt->bar0 = NULL;
0283     }
0284     if (cobalt->bar1) {
0285         pci_iounmap(pci_dev, cobalt->bar1);
0286         cobalt->bar1 = NULL;
0287     }
0288 }
0289 
0290 static void cobalt_free_msi(struct cobalt *cobalt, struct pci_dev *pci_dev)
0291 {
0292     free_irq(pci_dev->irq, (void *)cobalt);
0293     pci_free_irq_vectors(pci_dev);
0294 }
0295 
0296 static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev,
0297                 const struct pci_device_id *pci_id)
0298 {
0299     u32 ctrl;
0300     int ret;
0301 
0302     cobalt_dbg(1, "enabling pci device\n");
0303 
0304     ret = pci_enable_device(pci_dev);
0305     if (ret) {
0306         cobalt_err("can't enable device\n");
0307         return ret;
0308     }
0309     pci_set_master(pci_dev);
0310     pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cobalt->card_rev);
0311     pci_read_config_word(pci_dev, PCI_DEVICE_ID, &cobalt->device_id);
0312 
0313     switch (cobalt->device_id) {
0314     case PCI_DEVICE_ID_COBALT:
0315         cobalt_info("PCI Express interface from Omnitek\n");
0316         break;
0317     default:
0318         cobalt_info("PCI Express interface provider is unknown!\n");
0319         break;
0320     }
0321 
0322     if (pcie_link_get_lanes(cobalt) != 8) {
0323         cobalt_warn("PCI Express link width is %d lanes.\n",
0324                 pcie_link_get_lanes(cobalt));
0325         if (pcie_bus_link_get_lanes(cobalt) < 8)
0326             cobalt_warn("The current slot only supports %d lanes, for best performance 8 are needed\n",
0327                     pcie_bus_link_get_lanes(cobalt));
0328         if (pcie_link_get_lanes(cobalt) != pcie_bus_link_get_lanes(cobalt)) {
0329             cobalt_err("The card is most likely not seated correctly in the PCIe slot\n");
0330             ret = -EIO;
0331             goto err_disable;
0332         }
0333     }
0334 
0335     if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64))) {
0336         ret = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32));
0337         if (ret) {
0338             cobalt_err("no suitable DMA available\n");
0339             goto err_disable;
0340         }
0341     }
0342 
0343     ret = pci_request_regions(pci_dev, "cobalt");
0344     if (ret) {
0345         cobalt_err("error requesting regions\n");
0346         goto err_disable;
0347     }
0348 
0349     cobalt_pcie_status_show(cobalt);
0350 
0351     cobalt->bar0 = pci_iomap(pci_dev, 0, 0);
0352     cobalt->bar1 = pci_iomap(pci_dev, 1, 0);
0353     if (cobalt->bar1 == NULL) {
0354         cobalt->bar1 = pci_iomap(pci_dev, 2, 0);
0355         cobalt_info("64-bit BAR\n");
0356     }
0357     if (!cobalt->bar0 || !cobalt->bar1) {
0358         ret = -EIO;
0359         goto err_release;
0360     }
0361 
0362     /* Reset the video inputs before enabling any interrupts */
0363     ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE);
0364     cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, ctrl & ~0xf00);
0365 
0366     /* Disable interrupts to prevent any spurious interrupts
0367        from being generated. */
0368     cobalt_set_interrupt(cobalt, false);
0369 
0370     if (pci_alloc_irq_vectors(pci_dev, 1, 1, PCI_IRQ_MSI) < 1) {
0371         cobalt_err("Could not enable MSI\n");
0372         ret = -EIO;
0373         goto err_release;
0374     }
0375     msi_config_show(cobalt, pci_dev);
0376 
0377     /* Register IRQ */
0378     if (request_irq(pci_dev->irq, cobalt_irq_handler, IRQF_SHARED,
0379             cobalt->v4l2_dev.name, (void *)cobalt)) {
0380         cobalt_err("Failed to register irq %d\n", pci_dev->irq);
0381         ret = -EIO;
0382         goto err_msi;
0383     }
0384 
0385     omni_sg_dma_init(cobalt);
0386     return 0;
0387 
0388 err_msi:
0389     pci_disable_msi(pci_dev);
0390 
0391 err_release:
0392     cobalt_pci_iounmap(cobalt, pci_dev);
0393     pci_release_regions(pci_dev);
0394 
0395 err_disable:
0396     pci_disable_device(cobalt->pci_dev);
0397     return ret;
0398 }
0399 
0400 static int cobalt_hdl_info_get(struct cobalt *cobalt)
0401 {
0402     int i;
0403 
0404     for (i = 0; i < COBALT_HDL_INFO_SIZE; i++)
0405         cobalt->hdl_info[i] =
0406             ioread8(cobalt->bar1 + COBALT_HDL_INFO_BASE + i);
0407     cobalt->hdl_info[COBALT_HDL_INFO_SIZE - 1] = '\0';
0408     if (strstr(cobalt->hdl_info, COBALT_HDL_SEARCH_STR))
0409         return 0;
0410 
0411     return 1;
0412 }
0413 
0414 static void cobalt_stream_struct_init(struct cobalt *cobalt)
0415 {
0416     int i;
0417 
0418     for (i = 0; i < COBALT_NUM_STREAMS; i++) {
0419         struct cobalt_stream *s = &cobalt->streams[i];
0420 
0421         s->cobalt = cobalt;
0422         s->flags = 0;
0423         s->is_audio = false;
0424         s->is_output = false;
0425         s->is_dummy = true;
0426 
0427         /* The Memory DMA channels will always get a lower channel
0428          * number than the FIFO DMA. Video input should map to the
0429          * stream 0-3. The other can use stream struct from 4 and
0430          * higher */
0431         if (i <= COBALT_HSMA_IN_NODE) {
0432             s->dma_channel = i + cobalt->first_fifo_channel;
0433             s->video_channel = i;
0434             s->dma_fifo_mask =
0435                 COBALT_SYSSTAT_VI0_LOST_DATA_MSK << (4 * i);
0436             s->adv_irq_mask =
0437                 COBALT_SYSSTAT_VI0_INT1_MSK << (4 * i);
0438         } else if (i >= COBALT_AUDIO_IN_STREAM &&
0439                i <= COBALT_AUDIO_IN_STREAM + 4) {
0440             unsigned idx = i - COBALT_AUDIO_IN_STREAM;
0441 
0442             s->dma_channel = 6 + idx;
0443             s->is_audio = true;
0444             s->video_channel = idx;
0445             s->dma_fifo_mask = COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK;
0446         } else if (i == COBALT_HSMA_OUT_NODE) {
0447             s->dma_channel = 11;
0448             s->is_output = true;
0449             s->video_channel = 5;
0450             s->dma_fifo_mask = COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK;
0451             s->adv_irq_mask = COBALT_SYSSTAT_VOHSMA_INT1_MSK;
0452         } else if (i == COBALT_AUDIO_OUT_STREAM) {
0453             s->dma_channel = 12;
0454             s->is_audio = true;
0455             s->is_output = true;
0456             s->video_channel = 5;
0457             s->dma_fifo_mask = COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK;
0458         } else {
0459             /* FIXME: Memory DMA for debug purpose */
0460             s->dma_channel = i - COBALT_NUM_NODES;
0461         }
0462         cobalt_info("stream #%d -> dma channel #%d <- video channel %d\n",
0463                 i, s->dma_channel, s->video_channel);
0464     }
0465 }
0466 
0467 static int cobalt_subdevs_init(struct cobalt *cobalt)
0468 {
0469     static struct adv76xx_platform_data adv7604_pdata = {
0470         .disable_pwrdnb = 1,
0471         .ain_sel = ADV7604_AIN7_8_9_NC_SYNC_3_1,
0472         .bus_order = ADV7604_BUS_ORDER_BRG,
0473         .blank_data = 1,
0474         .op_format_mode_sel = ADV7604_OP_FORMAT_MODE0,
0475         .int1_config = ADV76XX_INT1_CONFIG_ACTIVE_HIGH,
0476         .dr_str_data = ADV76XX_DR_STR_HIGH,
0477         .dr_str_clk = ADV76XX_DR_STR_HIGH,
0478         .dr_str_sync = ADV76XX_DR_STR_HIGH,
0479         .hdmi_free_run_mode = 1,
0480         .inv_vs_pol = 1,
0481         .inv_hs_pol = 1,
0482     };
0483     static struct i2c_board_info adv7604_info = {
0484         .type = "adv7604",
0485         .addr = 0x20,
0486         .platform_data = &adv7604_pdata,
0487     };
0488 
0489     struct cobalt_stream *s = cobalt->streams;
0490     int i;
0491 
0492     for (i = 0; i < COBALT_NUM_INPUTS; i++) {
0493         struct v4l2_subdev_format sd_fmt = {
0494             .pad = ADV7604_PAD_SOURCE,
0495             .which = V4L2_SUBDEV_FORMAT_ACTIVE,
0496             .format.code = MEDIA_BUS_FMT_YUYV8_1X16,
0497         };
0498         struct v4l2_subdev_edid cobalt_edid = {
0499             .pad = ADV76XX_PAD_HDMI_PORT_A,
0500             .start_block = 0,
0501             .blocks = 2,
0502             .edid = edid,
0503         };
0504         int err;
0505 
0506         s[i].pad_source = ADV7604_PAD_SOURCE;
0507         s[i].i2c_adap = &cobalt->i2c_adap[i];
0508         if (s[i].i2c_adap->dev.parent == NULL)
0509             continue;
0510         cobalt_s_bit_sysctrl(cobalt,
0511                 COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(i), 1);
0512         s[i].sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev,
0513             s[i].i2c_adap, &adv7604_info, NULL);
0514         if (!s[i].sd) {
0515             if (cobalt_ignore_err)
0516                 continue;
0517             return -ENODEV;
0518         }
0519         err = v4l2_subdev_call(s[i].sd, video, s_routing,
0520                 ADV76XX_PAD_HDMI_PORT_A, 0, 0);
0521         if (err)
0522             return err;
0523         err = v4l2_subdev_call(s[i].sd, pad, set_edid,
0524                 &cobalt_edid);
0525         if (err)
0526             return err;
0527         err = v4l2_subdev_call(s[i].sd, pad, set_fmt, NULL,
0528                 &sd_fmt);
0529         if (err)
0530             return err;
0531         /* Reset channel video module */
0532         cobalt_s_bit_sysctrl(cobalt,
0533                 COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(i), 0);
0534         mdelay(2);
0535         cobalt_s_bit_sysctrl(cobalt,
0536                 COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(i), 1);
0537         mdelay(1);
0538         s[i].is_dummy = false;
0539         cobalt->streams[i + COBALT_AUDIO_IN_STREAM].is_dummy = false;
0540     }
0541     return 0;
0542 }
0543 
0544 static int cobalt_subdevs_hsma_init(struct cobalt *cobalt)
0545 {
0546     static struct adv7842_platform_data adv7842_pdata = {
0547         .disable_pwrdnb = 1,
0548         .ain_sel = ADV7842_AIN1_2_3_NC_SYNC_1_2,
0549         .bus_order = ADV7842_BUS_ORDER_RBG,
0550         .op_format_mode_sel = ADV7842_OP_FORMAT_MODE0,
0551         .blank_data = 1,
0552         .dr_str_data = 3,
0553         .dr_str_clk = 3,
0554         .dr_str_sync = 3,
0555         .mode = ADV7842_MODE_HDMI,
0556         .hdmi_free_run_enable = 1,
0557         .vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P,
0558         .i2c_sdp_io = 0x4a,
0559         .i2c_sdp = 0x48,
0560         .i2c_cp = 0x22,
0561         .i2c_vdp = 0x24,
0562         .i2c_afe = 0x26,
0563         .i2c_hdmi = 0x34,
0564         .i2c_repeater = 0x32,
0565         .i2c_edid = 0x36,
0566         .i2c_infoframe = 0x3e,
0567         .i2c_cec = 0x40,
0568         .i2c_avlink = 0x42,
0569     };
0570     static struct i2c_board_info adv7842_info = {
0571         .type = "adv7842",
0572         .addr = 0x20,
0573         .platform_data = &adv7842_pdata,
0574     };
0575     struct v4l2_subdev_format sd_fmt = {
0576         .pad = ADV7842_PAD_SOURCE,
0577         .which = V4L2_SUBDEV_FORMAT_ACTIVE,
0578         .format.code = MEDIA_BUS_FMT_YUYV8_1X16,
0579     };
0580     static struct adv7511_platform_data adv7511_pdata = {
0581         .i2c_edid = 0x7e >> 1,
0582         .i2c_cec = 0x7c >> 1,
0583         .i2c_pktmem = 0x70 >> 1,
0584         .cec_clk = 12000000,
0585     };
0586     static struct i2c_board_info adv7511_info = {
0587         .type = "adv7511-v4l2",
0588         .addr = 0x39, /* 0x39 or 0x3d */
0589         .platform_data = &adv7511_pdata,
0590     };
0591     struct v4l2_subdev_edid cobalt_edid = {
0592         .pad = ADV7842_EDID_PORT_A,
0593         .start_block = 0,
0594         .blocks = 2,
0595         .edid = edid,
0596     };
0597     struct cobalt_stream *s = &cobalt->streams[COBALT_HSMA_IN_NODE];
0598 
0599     s->i2c_adap = &cobalt->i2c_adap[COBALT_NUM_ADAPTERS - 1];
0600     if (s->i2c_adap->dev.parent == NULL)
0601         return 0;
0602     cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(4), 1);
0603 
0604     s->sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev,
0605             s->i2c_adap, &adv7842_info, NULL);
0606     if (s->sd) {
0607         int err = v4l2_subdev_call(s->sd, pad, set_edid, &cobalt_edid);
0608 
0609         if (err)
0610             return err;
0611         err = v4l2_subdev_call(s->sd, pad, set_fmt, NULL,
0612                 &sd_fmt);
0613         if (err)
0614             return err;
0615         cobalt->have_hsma_rx = true;
0616         s->pad_source = ADV7842_PAD_SOURCE;
0617         s->is_dummy = false;
0618         cobalt->streams[4 + COBALT_AUDIO_IN_STREAM].is_dummy = false;
0619         /* Reset channel video module */
0620         cobalt_s_bit_sysctrl(cobalt,
0621                 COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 0);
0622         mdelay(2);
0623         cobalt_s_bit_sysctrl(cobalt,
0624                 COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 1);
0625         mdelay(1);
0626         return err;
0627     }
0628     cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(4), 0);
0629     cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_PWRDN0_TO_HSMA_TX_BIT, 0);
0630     s++;
0631     s->i2c_adap = &cobalt->i2c_adap[COBALT_NUM_ADAPTERS - 1];
0632     s->sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev,
0633             s->i2c_adap, &adv7511_info, NULL);
0634     if (s->sd) {
0635         /* A transmitter is hooked up, so we can set this bit */
0636         cobalt_s_bit_sysctrl(cobalt,
0637                 COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 1);
0638         cobalt_s_bit_sysctrl(cobalt,
0639                 COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 0);
0640         cobalt_s_bit_sysctrl(cobalt,
0641                 COBALT_SYS_CTRL_VIDEO_TX_RESETN_BIT, 1);
0642         cobalt->have_hsma_tx = true;
0643         v4l2_subdev_call(s->sd, core, s_power, 1);
0644         v4l2_subdev_call(s->sd, video, s_stream, 1);
0645         v4l2_subdev_call(s->sd, audio, s_stream, 1);
0646         v4l2_ctrl_s_ctrl(v4l2_ctrl_find(s->sd->ctrl_handler,
0647                  V4L2_CID_DV_TX_MODE), V4L2_DV_TX_MODE_HDMI);
0648         s->is_dummy = false;
0649         cobalt->streams[COBALT_AUDIO_OUT_STREAM].is_dummy = false;
0650         return 0;
0651     }
0652     return -ENODEV;
0653 }
0654 
0655 static int cobalt_probe(struct pci_dev *pci_dev,
0656                   const struct pci_device_id *pci_id)
0657 {
0658     struct cobalt *cobalt;
0659     int retval = 0;
0660     int i;
0661 
0662     /* FIXME - module parameter arrays constrain max instances */
0663     i = atomic_inc_return(&cobalt_instance) - 1;
0664 
0665     cobalt = kzalloc(sizeof(struct cobalt), GFP_KERNEL);
0666     if (cobalt == NULL)
0667         return -ENOMEM;
0668     cobalt->pci_dev = pci_dev;
0669     cobalt->instance = i;
0670     mutex_init(&cobalt->pci_lock);
0671 
0672     retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev);
0673     if (retval) {
0674         pr_err("cobalt: v4l2_device_register of card %d failed\n",
0675                 cobalt->instance);
0676         kfree(cobalt);
0677         return retval;
0678     }
0679     snprintf(cobalt->v4l2_dev.name, sizeof(cobalt->v4l2_dev.name),
0680          "cobalt-%d", cobalt->instance);
0681     cobalt->v4l2_dev.notify = cobalt_notify;
0682     cobalt_info("Initializing card %d\n", cobalt->instance);
0683 
0684     cobalt->irq_work_queues =
0685         create_singlethread_workqueue(cobalt->v4l2_dev.name);
0686     if (cobalt->irq_work_queues == NULL) {
0687         cobalt_err("Could not create workqueue\n");
0688         retval = -ENOMEM;
0689         goto err;
0690     }
0691 
0692     INIT_WORK(&cobalt->irq_work_queue, cobalt_irq_work_handler);
0693 
0694     /* PCI Device Setup */
0695     retval = cobalt_setup_pci(cobalt, pci_dev, pci_id);
0696     if (retval != 0)
0697         goto err_wq;
0698 
0699     /* Show HDL version info */
0700     if (cobalt_hdl_info_get(cobalt))
0701         cobalt_info("Not able to read the HDL info\n");
0702     else
0703         cobalt_info("%s", cobalt->hdl_info);
0704 
0705     retval = cobalt_i2c_init(cobalt);
0706     if (retval)
0707         goto err_pci;
0708 
0709     cobalt_stream_struct_init(cobalt);
0710 
0711     retval = cobalt_subdevs_init(cobalt);
0712     if (retval)
0713         goto err_i2c;
0714 
0715     if (!(cobalt_read_bar1(cobalt, COBALT_SYS_STAT_BASE) &
0716             COBALT_SYSSTAT_HSMA_PRSNTN_MSK)) {
0717         retval = cobalt_subdevs_hsma_init(cobalt);
0718         if (retval)
0719             goto err_i2c;
0720     }
0721 
0722     retval = cobalt_nodes_register(cobalt);
0723     if (retval) {
0724         cobalt_err("Error %d registering device nodes\n", retval);
0725         goto err_i2c;
0726     }
0727     cobalt_set_interrupt(cobalt, true);
0728     v4l2_device_call_all(&cobalt->v4l2_dev, 0, core,
0729                     interrupt_service_routine, 0, NULL);
0730 
0731     cobalt_info("Initialized cobalt card\n");
0732 
0733     cobalt_flash_probe(cobalt);
0734 
0735     return 0;
0736 
0737 err_i2c:
0738     cobalt_i2c_exit(cobalt);
0739     cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 0);
0740 err_pci:
0741     cobalt_free_msi(cobalt, pci_dev);
0742     cobalt_pci_iounmap(cobalt, pci_dev);
0743     pci_release_regions(cobalt->pci_dev);
0744     pci_disable_device(cobalt->pci_dev);
0745 err_wq:
0746     destroy_workqueue(cobalt->irq_work_queues);
0747 err:
0748     cobalt_err("error %d on initialization\n", retval);
0749 
0750     v4l2_device_unregister(&cobalt->v4l2_dev);
0751     kfree(cobalt);
0752     return retval;
0753 }
0754 
0755 static void cobalt_remove(struct pci_dev *pci_dev)
0756 {
0757     struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
0758     struct cobalt *cobalt = to_cobalt(v4l2_dev);
0759     int i;
0760 
0761     cobalt_flash_remove(cobalt);
0762     cobalt_set_interrupt(cobalt, false);
0763     flush_workqueue(cobalt->irq_work_queues);
0764     cobalt_nodes_unregister(cobalt);
0765     for (i = 0; i < COBALT_NUM_ADAPTERS; i++) {
0766         struct v4l2_subdev *sd = cobalt->streams[i].sd;
0767         struct i2c_client *client;
0768 
0769         if (sd == NULL)
0770             continue;
0771         client = v4l2_get_subdevdata(sd);
0772         v4l2_device_unregister_subdev(sd);
0773         i2c_unregister_device(client);
0774     }
0775     cobalt_i2c_exit(cobalt);
0776     cobalt_free_msi(cobalt, pci_dev);
0777     cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 0);
0778     cobalt_pci_iounmap(cobalt, pci_dev);
0779     pci_release_regions(cobalt->pci_dev);
0780     pci_disable_device(cobalt->pci_dev);
0781     destroy_workqueue(cobalt->irq_work_queues);
0782 
0783     cobalt_info("removed cobalt card\n");
0784 
0785     v4l2_device_unregister(v4l2_dev);
0786     kfree(cobalt);
0787 }
0788 
0789 /* define a pci_driver for card detection */
0790 static struct pci_driver cobalt_pci_driver = {
0791     .name =     "cobalt",
0792     .id_table = cobalt_pci_tbl,
0793     .probe =    cobalt_probe,
0794     .remove =   cobalt_remove,
0795 };
0796 
0797 module_pci_driver(cobalt_pci_driver);