linux/drivers/media/pci/cobalt/cobalt-driver.c
<<
>>
Prefs
   1/*
   2 *  cobalt driver initialization and card probing
   3 *
   4 *  Derived from cx18-driver.c
   5 *
   6 *  Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates.
   7 *  All rights reserved.
   8 *
   9 *  This program is free software; you may redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License as published by
  11 *  the Free Software Foundation; version 2 of the License.
  12 *
  13 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17 *  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18 *  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20 *  SOFTWARE.
  21 */
  22
  23#include <linux/delay.h>
  24#include <media/i2c/adv7604.h>
  25#include <media/i2c/adv7842.h>
  26#include <media/i2c/adv7511.h>
  27#include <media/v4l2-event.h>
  28#include <media/v4l2-ctrls.h>
  29
  30#include "cobalt-driver.h"
  31#include "cobalt-irq.h"
  32#include "cobalt-i2c.h"
  33#include "cobalt-v4l2.h"
  34#include "cobalt-flash.h"
  35#include "cobalt-alsa.h"
  36#include "cobalt-omnitek.h"
  37
  38/* add your revision and whatnot here */
  39static struct pci_device_id cobalt_pci_tbl[] = {
  40        {PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_COBALT,
  41         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
  42        {0,}
  43};
  44
  45MODULE_DEVICE_TABLE(pci, cobalt_pci_tbl);
  46
  47static atomic_t cobalt_instance = ATOMIC_INIT(0);
  48
  49int cobalt_debug;
  50module_param_named(debug, cobalt_debug, int, 0644);
  51MODULE_PARM_DESC(debug, "Debug level. Default: 0\n");
  52
  53int cobalt_ignore_err;
  54module_param_named(ignore_err, cobalt_ignore_err, int, 0644);
  55MODULE_PARM_DESC(ignore_err,
  56        "If set then ignore missing i2c adapters/receivers. Default: 0\n");
  57
  58MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com> & Morten Hestnes");
  59MODULE_DESCRIPTION("cobalt driver");
  60MODULE_LICENSE("GPL");
  61
  62static u8 edid[256] = {
  63        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
  64        0x50, 0x21, 0x9C, 0x27, 0x00, 0x00, 0x00, 0x00,
  65        0x19, 0x12, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78,
  66        0x0E, 0x00, 0xB2, 0xA0, 0x57, 0x49, 0x9B, 0x26,
  67        0x10, 0x48, 0x4F, 0x2F, 0xCF, 0x00, 0x31, 0x59,
  68        0x45, 0x59, 0x61, 0x59, 0x81, 0x99, 0x01, 0x01,
  69        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A,
  70        0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
  71        0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E,
  72        0x00, 0x00, 0x00, 0xFD, 0x00, 0x31, 0x55, 0x18,
  73        0x5E, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20,
  74        0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x43,
  75        0x20, 0x39, 0x30, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
  76        0x0A, 0x0A, 0x0A, 0x0A, 0x00, 0x00, 0x00, 0x10,
  77        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  78        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68,
  79        0x02, 0x03, 0x1a, 0xc0, 0x48, 0xa2, 0x10, 0x04,
  80        0x02, 0x01, 0x21, 0x14, 0x13, 0x23, 0x09, 0x07,
  81        0x07, 0x65, 0x03, 0x0c, 0x00, 0x10, 0x00, 0xe2,
  82        0x00, 0x2a, 0x01, 0x1d, 0x00, 0x80, 0x51, 0xd0,
  83        0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0x00, 0x00,
  84        0x00, 0x00, 0x00, 0x1e, 0x8c, 0x0a, 0xd0, 0x8a,
  85        0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00,
  86        0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
  87        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  88        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  89        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  90        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  91        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  92        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  93        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  94        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7
  95};
  96
  97static void cobalt_set_interrupt(struct cobalt *cobalt, bool enable)
  98{
  99        if (enable) {
 100                unsigned irqs = COBALT_SYSSTAT_VI0_INT1_MSK |
 101                                COBALT_SYSSTAT_VI1_INT1_MSK |
 102                                COBALT_SYSSTAT_VI2_INT1_MSK |
 103                                COBALT_SYSSTAT_VI3_INT1_MSK |
 104                                COBALT_SYSSTAT_VI0_INT2_MSK |
 105                                COBALT_SYSSTAT_VI1_INT2_MSK |
 106                                COBALT_SYSSTAT_VI2_INT2_MSK |
 107                                COBALT_SYSSTAT_VI3_INT2_MSK |
 108                                COBALT_SYSSTAT_VI0_LOST_DATA_MSK |
 109                                COBALT_SYSSTAT_VI1_LOST_DATA_MSK |
 110                                COBALT_SYSSTAT_VI2_LOST_DATA_MSK |
 111                                COBALT_SYSSTAT_VI3_LOST_DATA_MSK |
 112                                COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK;
 113
 114                if (cobalt->have_hsma_rx)
 115                        irqs |= COBALT_SYSSTAT_VIHSMA_INT1_MSK |
 116                                COBALT_SYSSTAT_VIHSMA_INT2_MSK |
 117                                COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK;
 118
 119                if (cobalt->have_hsma_tx)
 120                        irqs |= COBALT_SYSSTAT_VOHSMA_INT1_MSK |
 121                                COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK |
 122                                COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK;
 123                /* Clear any existing interrupts */
 124                cobalt_write_bar1(cobalt, COBALT_SYS_STAT_EDGE, 0xffffffff);
 125                /* PIO Core interrupt mask register.
 126                   Enable ADV7604 INT1 interrupts */
 127                cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, irqs);
 128        } else {
 129                /* Disable all ADV7604 interrupts */
 130                cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, 0);
 131        }
 132}
 133
 134static unsigned cobalt_get_sd_nr(struct v4l2_subdev *sd)
 135{
 136        struct cobalt *cobalt = to_cobalt(sd->v4l2_dev);
 137        unsigned i;
 138
 139        for (i = 0; i < COBALT_NUM_NODES; i++)
 140                if (sd == cobalt->streams[i].sd)
 141                        return i;
 142        cobalt_err("Invalid adv7604 subdev pointer!\n");
 143        return 0;
 144}
 145
 146static void cobalt_notify(struct v4l2_subdev *sd,
 147                          unsigned int notification, void *arg)
 148{
 149        struct cobalt *cobalt = to_cobalt(sd->v4l2_dev);
 150        unsigned sd_nr = cobalt_get_sd_nr(sd);
 151        struct cobalt_stream *s = &cobalt->streams[sd_nr];
 152        bool hotplug = arg ? *((int *)arg) : false;
 153
 154        if (s->is_output)
 155                return;
 156
 157        switch (notification) {
 158        case ADV76XX_HOTPLUG:
 159                cobalt_s_bit_sysctrl(cobalt,
 160                        COBALT_SYS_CTRL_HPD_TO_CONNECTOR_BIT(sd_nr), hotplug);
 161                cobalt_dbg(1, "Set hotplug for adv %d to %d\n", sd_nr, hotplug);
 162                break;
 163        case V4L2_DEVICE_NOTIFY_EVENT:
 164                cobalt_dbg(1, "Format changed for adv %d\n", sd_nr);
 165                v4l2_event_queue(&s->vdev, arg);
 166                break;
 167        default:
 168                break;
 169        }
 170}
 171
 172static int get_payload_size(u16 code)
 173{
 174        switch (code) {
 175        case 0: return 128;
 176        case 1: return 256;
 177        case 2: return 512;
 178        case 3: return 1024;
 179        case 4: return 2048;
 180        case 5: return 4096;
 181        default: return 0;
 182        }
 183        return 0;
 184}
 185
 186static const char *get_link_speed(u16 stat)
 187{
 188        switch (stat & PCI_EXP_LNKSTA_CLS) {
 189        case 1: return "2.5 Gbit/s";
 190        case 2: return "5 Gbit/s";
 191        case 3: return "10 Gbit/s";
 192        }
 193        return "Unknown speed";
 194}
 195
 196void cobalt_pcie_status_show(struct cobalt *cobalt)
 197{
 198        struct pci_dev *pci_dev = cobalt->pci_dev;
 199        struct pci_dev *pci_bus_dev = cobalt->pci_dev->bus->self;
 200        int offset;
 201        int bus_offset;
 202        u32 capa;
 203        u16 stat, ctrl;
 204
 205        offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP);
 206        bus_offset = pci_find_capability(pci_bus_dev, PCI_CAP_ID_EXP);
 207
 208        /* Device */
 209        pci_read_config_dword(pci_dev, offset + PCI_EXP_DEVCAP, &capa);
 210        pci_read_config_word(pci_dev, offset + PCI_EXP_DEVCTL, &ctrl);
 211        pci_read_config_word(pci_dev, offset + PCI_EXP_DEVSTA, &stat);
 212        cobalt_info("PCIe device capability 0x%08x: Max payload %d\n",
 213                    capa, get_payload_size(capa & PCI_EXP_DEVCAP_PAYLOAD));
 214        cobalt_info("PCIe device control 0x%04x: Max payload %d. Max read request %d\n",
 215                    ctrl,
 216                    get_payload_size((ctrl & PCI_EXP_DEVCTL_PAYLOAD) >> 5),
 217                    get_payload_size((ctrl & PCI_EXP_DEVCTL_READRQ) >> 12));
 218        cobalt_info("PCIe device status 0x%04x\n", stat);
 219
 220        /* Link */
 221        pci_read_config_dword(pci_dev, offset + PCI_EXP_LNKCAP, &capa);
 222        pci_read_config_word(pci_dev, offset + PCI_EXP_LNKCTL, &ctrl);
 223        pci_read_config_word(pci_dev, offset + PCI_EXP_LNKSTA, &stat);
 224        cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n",
 225                        capa, get_link_speed(capa),
 226                        (capa & PCI_EXP_LNKCAP_MLW) >> 4);
 227        cobalt_info("PCIe link control 0x%04x\n", ctrl);
 228        cobalt_info("PCIe link status 0x%04x: %s per lane and %u lanes\n",
 229                    stat, get_link_speed(stat),
 230                    (stat & PCI_EXP_LNKSTA_NLW) >> 4);
 231
 232        /* Bus */
 233        pci_read_config_dword(pci_bus_dev, bus_offset + PCI_EXP_LNKCAP, &capa);
 234        cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n",
 235                        capa, get_link_speed(capa),
 236                        (capa & PCI_EXP_LNKCAP_MLW) >> 4);
 237
 238        /* Slot */
 239        pci_read_config_dword(pci_dev, offset + PCI_EXP_SLTCAP, &capa);
 240        pci_read_config_word(pci_dev, offset + PCI_EXP_SLTCTL, &ctrl);
 241        pci_read_config_word(pci_dev, offset + PCI_EXP_SLTSTA, &stat);
 242        cobalt_info("PCIe slot capability 0x%08x\n", capa);
 243        cobalt_info("PCIe slot control 0x%04x\n", ctrl);
 244        cobalt_info("PCIe slot status 0x%04x\n", stat);
 245}
 246
 247static unsigned pcie_link_get_lanes(struct cobalt *cobalt)
 248{
 249        struct pci_dev *pci_dev = cobalt->pci_dev;
 250        unsigned offset;
 251        u16 link;
 252
 253        offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP);
 254        if (!offset)
 255                return 0;
 256        pci_read_config_word(pci_dev, offset + PCI_EXP_LNKSTA, &link);
 257        return (link & PCI_EXP_LNKSTA_NLW) >> 4;
 258}
 259
 260static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt)
 261{
 262        struct pci_dev *pci_dev = cobalt->pci_dev->bus->self;
 263        unsigned offset;
 264        u32 link;
 265
 266        offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP);
 267        if (!offset)
 268                return 0;
 269        pci_read_config_dword(pci_dev, offset + PCI_EXP_LNKCAP, &link);
 270        return (link & PCI_EXP_LNKCAP_MLW) >> 4;
 271}
 272
 273static void msi_config_show(struct cobalt *cobalt, struct pci_dev *pci_dev)
 274{
 275        u16 ctrl, data;
 276        u32 adrs_l, adrs_h;
 277
 278        pci_read_config_word(pci_dev, 0x52, &ctrl);
 279        cobalt_info("MSI %s\n", ctrl & 1 ? "enable" : "disable");
 280        cobalt_info("MSI multiple message: Capable %u. Enable %u\n",
 281                    (1 << ((ctrl >> 1) & 7)), (1 << ((ctrl >> 4) & 7)));
 282        if (ctrl & 0x80)
 283                cobalt_info("MSI: 64-bit address capable\n");
 284        pci_read_config_dword(pci_dev, 0x54, &adrs_l);
 285        pci_read_config_dword(pci_dev, 0x58, &adrs_h);
 286        pci_read_config_word(pci_dev, 0x5c, &data);
 287        if (ctrl & 0x80)
 288                cobalt_info("MSI: Address 0x%08x%08x. Data 0x%04x\n",
 289                                adrs_h, adrs_l, data);
 290        else
 291                cobalt_info("MSI: Address 0x%08x. Data 0x%04x\n",
 292                                adrs_l, data);
 293}
 294
 295static void cobalt_pci_iounmap(struct cobalt *cobalt, struct pci_dev *pci_dev)
 296{
 297        if (cobalt->bar0) {
 298                pci_iounmap(pci_dev, cobalt->bar0);
 299                cobalt->bar0 = NULL;
 300        }
 301        if (cobalt->bar1) {
 302                pci_iounmap(pci_dev, cobalt->bar1);
 303                cobalt->bar1 = NULL;
 304        }
 305}
 306
 307static void cobalt_free_msi(struct cobalt *cobalt, struct pci_dev *pci_dev)
 308{
 309        free_irq(pci_dev->irq, (void *)cobalt);
 310
 311        if (cobalt->msi_enabled)
 312                pci_disable_msi(pci_dev);
 313}
 314
 315static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev,
 316                            const struct pci_device_id *pci_id)
 317{
 318        u32 ctrl;
 319        int ret;
 320
 321        cobalt_dbg(1, "enabling pci device\n");
 322
 323        ret = pci_enable_device(pci_dev);
 324        if (ret) {
 325                cobalt_err("can't enable device\n");
 326                return ret;
 327        }
 328        pci_set_master(pci_dev);
 329        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cobalt->card_rev);
 330        pci_read_config_word(pci_dev, PCI_DEVICE_ID, &cobalt->device_id);
 331
 332        switch (cobalt->device_id) {
 333        case PCI_DEVICE_ID_COBALT:
 334                cobalt_info("PCI Express interface from Omnitek\n");
 335                break;
 336        default:
 337                cobalt_info("PCI Express interface provider is unknown!\n");
 338                break;
 339        }
 340
 341        if (pcie_link_get_lanes(cobalt) != 8) {
 342                cobalt_warn("PCI Express link width is %d lanes.\n",
 343                                pcie_link_get_lanes(cobalt));
 344                if (pcie_bus_link_get_lanes(cobalt) < 8)
 345                        cobalt_warn("The current slot only supports %d lanes, for best performance 8 are needed\n",
 346                                        pcie_bus_link_get_lanes(cobalt));
 347                if (pcie_link_get_lanes(cobalt) != pcie_bus_link_get_lanes(cobalt)) {
 348                        cobalt_err("The card is most likely not seated correctly in the PCIe slot\n");
 349                        ret = -EIO;
 350                        goto err_disable;
 351                }
 352        }
 353
 354        if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) {
 355                ret = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
 356                if (ret) {
 357                        cobalt_err("no suitable DMA available\n");
 358                        goto err_disable;
 359                }
 360        }
 361
 362        ret = pci_request_regions(pci_dev, "cobalt");
 363        if (ret) {
 364                cobalt_err("error requesting regions\n");
 365                goto err_disable;
 366        }
 367
 368        cobalt_pcie_status_show(cobalt);
 369
 370        cobalt->bar0 = pci_iomap(pci_dev, 0, 0);
 371        cobalt->bar1 = pci_iomap(pci_dev, 1, 0);
 372        if (cobalt->bar1 == NULL) {
 373                cobalt->bar1 = pci_iomap(pci_dev, 2, 0);
 374                cobalt_info("64-bit BAR\n");
 375        }
 376        if (!cobalt->bar0 || !cobalt->bar1) {
 377                ret = -EIO;
 378                goto err_release;
 379        }
 380
 381        /* Reset the video inputs before enabling any interrupts */
 382        ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE);
 383        cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, ctrl & ~0xf00);
 384
 385        /* Disable interrupts to prevent any spurious interrupts
 386           from being generated. */
 387        cobalt_set_interrupt(cobalt, false);
 388
 389        if (pci_enable_msi_range(pci_dev, 1, 1) < 1) {
 390                cobalt_err("Could not enable MSI\n");
 391                cobalt->msi_enabled = false;
 392                ret = -EIO;
 393                goto err_release;
 394        }
 395        msi_config_show(cobalt, pci_dev);
 396        cobalt->msi_enabled = true;
 397
 398        /* Register IRQ */
 399        if (request_irq(pci_dev->irq, cobalt_irq_handler, IRQF_SHARED,
 400                        cobalt->v4l2_dev.name, (void *)cobalt)) {
 401                cobalt_err("Failed to register irq %d\n", pci_dev->irq);
 402                ret = -EIO;
 403                goto err_msi;
 404        }
 405
 406        omni_sg_dma_init(cobalt);
 407        return 0;
 408
 409err_msi:
 410        pci_disable_msi(pci_dev);
 411
 412err_release:
 413        cobalt_pci_iounmap(cobalt, pci_dev);
 414        pci_release_regions(pci_dev);
 415
 416err_disable:
 417        pci_disable_device(cobalt->pci_dev);
 418        return ret;
 419}
 420
 421static int cobalt_hdl_info_get(struct cobalt *cobalt)
 422{
 423        int i;
 424
 425        for (i = 0; i < COBALT_HDL_INFO_SIZE; i++)
 426                cobalt->hdl_info[i] =
 427                        ioread8(cobalt->bar1 + COBALT_HDL_INFO_BASE + i);
 428        cobalt->hdl_info[COBALT_HDL_INFO_SIZE - 1] = '\0';
 429        if (strstr(cobalt->hdl_info, COBALT_HDL_SEARCH_STR))
 430                return 0;
 431
 432        return 1;
 433}
 434
 435static void cobalt_stream_struct_init(struct cobalt *cobalt)
 436{
 437        int i;
 438
 439        for (i = 0; i < COBALT_NUM_STREAMS; i++) {
 440                struct cobalt_stream *s = &cobalt->streams[i];
 441
 442                s->cobalt = cobalt;
 443                s->flags = 0;
 444                s->is_audio = false;
 445                s->is_output = false;
 446                s->is_dummy = true;
 447
 448                /* The Memory DMA channels will always get a lower channel
 449                 * number than the FIFO DMA. Video input should map to the
 450                 * stream 0-3. The other can use stream struct from 4 and
 451                 * higher */
 452                if (i <= COBALT_HSMA_IN_NODE) {
 453                        s->dma_channel = i + cobalt->first_fifo_channel;
 454                        s->video_channel = i;
 455                        s->dma_fifo_mask =
 456                                COBALT_SYSSTAT_VI0_LOST_DATA_MSK << (4 * i);
 457                        s->adv_irq_mask =
 458                                COBALT_SYSSTAT_VI0_INT1_MSK << (4 * i);
 459                } else if (i >= COBALT_AUDIO_IN_STREAM &&
 460                           i <= COBALT_AUDIO_IN_STREAM + 4) {
 461                        unsigned idx = i - COBALT_AUDIO_IN_STREAM;
 462
 463                        s->dma_channel = 6 + idx;
 464                        s->is_audio = true;
 465                        s->video_channel = idx;
 466                        s->dma_fifo_mask = COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK;
 467                } else if (i == COBALT_HSMA_OUT_NODE) {
 468                        s->dma_channel = 11;
 469                        s->is_output = true;
 470                        s->video_channel = 5;
 471                        s->dma_fifo_mask = COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK;
 472                        s->adv_irq_mask = COBALT_SYSSTAT_VOHSMA_INT1_MSK;
 473                } else if (i == COBALT_AUDIO_OUT_STREAM) {
 474                        s->dma_channel = 12;
 475                        s->is_audio = true;
 476                        s->is_output = true;
 477                        s->video_channel = 5;
 478                        s->dma_fifo_mask = COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK;
 479                } else {
 480                        /* FIXME: Memory DMA for debug purpose */
 481                        s->dma_channel = i - COBALT_NUM_NODES;
 482                }
 483                cobalt_info("stream #%d -> dma channel #%d <- video channel %d\n",
 484                            i, s->dma_channel, s->video_channel);
 485        }
 486}
 487
 488static int cobalt_subdevs_init(struct cobalt *cobalt)
 489{
 490        static struct adv76xx_platform_data adv7604_pdata = {
 491                .disable_pwrdnb = 1,
 492                .ain_sel = ADV7604_AIN7_8_9_NC_SYNC_3_1,
 493                .bus_order = ADV7604_BUS_ORDER_BRG,
 494                .blank_data = 1,
 495                .op_656_range = 1,
 496                .op_format_mode_sel = ADV7604_OP_FORMAT_MODE0,
 497                .int1_config = ADV76XX_INT1_CONFIG_ACTIVE_HIGH,
 498                .dr_str_data = ADV76XX_DR_STR_HIGH,
 499                .dr_str_clk = ADV76XX_DR_STR_HIGH,
 500                .dr_str_sync = ADV76XX_DR_STR_HIGH,
 501                .hdmi_free_run_mode = 1,
 502                .inv_vs_pol = 1,
 503                .inv_hs_pol = 1,
 504        };
 505        static struct i2c_board_info adv7604_info = {
 506                .type = "adv7604",
 507                .addr = 0x20,
 508                .platform_data = &adv7604_pdata,
 509        };
 510
 511        struct cobalt_stream *s = cobalt->streams;
 512        int i;
 513
 514        for (i = 0; i < COBALT_NUM_INPUTS; i++) {
 515                struct v4l2_subdev_format sd_fmt = {
 516                        .pad = ADV7604_PAD_SOURCE,
 517                        .which = V4L2_SUBDEV_FORMAT_ACTIVE,
 518                        .format.code = MEDIA_BUS_FMT_YUYV8_1X16,
 519                };
 520                struct v4l2_subdev_edid cobalt_edid = {
 521                        .pad = ADV76XX_PAD_HDMI_PORT_A,
 522                        .start_block = 0,
 523                        .blocks = 2,
 524                        .edid = edid,
 525                };
 526                int err;
 527
 528                s[i].pad_source = ADV7604_PAD_SOURCE;
 529                s[i].i2c_adap = &cobalt->i2c_adap[i];
 530                if (s[i].i2c_adap->dev.parent == NULL)
 531                        continue;
 532                cobalt_s_bit_sysctrl(cobalt,
 533                                COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(i), 1);
 534                s[i].sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev,
 535                        s[i].i2c_adap, &adv7604_info, NULL);
 536                if (!s[i].sd) {
 537                        if (cobalt_ignore_err)
 538                                continue;
 539                        return -ENODEV;
 540                }
 541                err = v4l2_subdev_call(s[i].sd, video, s_routing,
 542                                ADV76XX_PAD_HDMI_PORT_A, 0, 0);
 543                if (err)
 544                        return err;
 545                err = v4l2_subdev_call(s[i].sd, pad, set_edid,
 546                                &cobalt_edid);
 547                if (err)
 548                        return err;
 549                err = v4l2_subdev_call(s[i].sd, pad, set_fmt, NULL,
 550                                &sd_fmt);
 551                if (err)
 552                        return err;
 553                /* Reset channel video module */
 554                cobalt_s_bit_sysctrl(cobalt,
 555                                COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(i), 0);
 556                mdelay(2);
 557                cobalt_s_bit_sysctrl(cobalt,
 558                                COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(i), 1);
 559                mdelay(1);
 560                s[i].is_dummy = false;
 561                cobalt->streams[i + COBALT_AUDIO_IN_STREAM].is_dummy = false;
 562        }
 563        return 0;
 564}
 565
 566static int cobalt_subdevs_hsma_init(struct cobalt *cobalt)
 567{
 568        static struct adv7842_platform_data adv7842_pdata = {
 569                .disable_pwrdnb = 1,
 570                .ain_sel = ADV7842_AIN1_2_3_NC_SYNC_1_2,
 571                .bus_order = ADV7842_BUS_ORDER_RBG,
 572                .op_format_mode_sel = ADV7842_OP_FORMAT_MODE0,
 573                .blank_data = 1,
 574                .op_656_range = 1,
 575                .dr_str_data = 3,
 576                .dr_str_clk = 3,
 577                .dr_str_sync = 3,
 578                .mode = ADV7842_MODE_HDMI,
 579                .hdmi_free_run_enable = 1,
 580                .vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P,
 581                .i2c_sdp_io = 0x4a,
 582                .i2c_sdp = 0x48,
 583                .i2c_cp = 0x22,
 584                .i2c_vdp = 0x24,
 585                .i2c_afe = 0x26,
 586                .i2c_hdmi = 0x34,
 587                .i2c_repeater = 0x32,
 588                .i2c_edid = 0x36,
 589                .i2c_infoframe = 0x3e,
 590                .i2c_cec = 0x40,
 591                .i2c_avlink = 0x42,
 592        };
 593        static struct i2c_board_info adv7842_info = {
 594                .type = "adv7842",
 595                .addr = 0x20,
 596                .platform_data = &adv7842_pdata,
 597        };
 598        static struct v4l2_subdev_format sd_fmt = {
 599                .pad = ADV7842_PAD_SOURCE,
 600                .which = V4L2_SUBDEV_FORMAT_ACTIVE,
 601                .format.code = MEDIA_BUS_FMT_YUYV8_1X16,
 602        };
 603        static struct adv7511_platform_data adv7511_pdata = {
 604                .i2c_edid = 0x7e >> 1,
 605                .i2c_cec = 0x7c >> 1,
 606                .i2c_pktmem = 0x70 >> 1,
 607                .cec_clk = 12000000,
 608        };
 609        static struct i2c_board_info adv7511_info = {
 610                .type = "adv7511",
 611                .addr = 0x39, /* 0x39 or 0x3d */
 612                .platform_data = &adv7511_pdata,
 613        };
 614        struct v4l2_subdev_edid cobalt_edid = {
 615                .pad = ADV7842_EDID_PORT_A,
 616                .start_block = 0,
 617                .blocks = 2,
 618                .edid = edid,
 619        };
 620        struct cobalt_stream *s = &cobalt->streams[COBALT_HSMA_IN_NODE];
 621
 622        s->i2c_adap = &cobalt->i2c_adap[COBALT_NUM_ADAPTERS - 1];
 623        if (s->i2c_adap->dev.parent == NULL)
 624                return 0;
 625        cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(4), 1);
 626
 627        s->sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev,
 628                        s->i2c_adap, &adv7842_info, NULL);
 629        if (s->sd) {
 630                int err = v4l2_subdev_call(s->sd, pad, set_edid, &cobalt_edid);
 631
 632                if (err)
 633                        return err;
 634                err = v4l2_subdev_call(s->sd, pad, set_fmt, NULL,
 635                                &sd_fmt);
 636                if (err)
 637                        return err;
 638                cobalt->have_hsma_rx = true;
 639                s->pad_source = ADV7842_PAD_SOURCE;
 640                s->is_dummy = false;
 641                cobalt->streams[4 + COBALT_AUDIO_IN_STREAM].is_dummy = false;
 642                /* Reset channel video module */
 643                cobalt_s_bit_sysctrl(cobalt,
 644                                COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 0);
 645                mdelay(2);
 646                cobalt_s_bit_sysctrl(cobalt,
 647                                COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 1);
 648                mdelay(1);
 649                return err;
 650        }
 651        cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(4), 0);
 652        cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_PWRDN0_TO_HSMA_TX_BIT, 0);
 653        s++;
 654        s->i2c_adap = &cobalt->i2c_adap[COBALT_NUM_ADAPTERS - 1];
 655        s->sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev,
 656                        s->i2c_adap, &adv7511_info, NULL);
 657        if (s->sd) {
 658                /* A transmitter is hooked up, so we can set this bit */
 659                cobalt_s_bit_sysctrl(cobalt,
 660                                COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 1);
 661                cobalt_s_bit_sysctrl(cobalt,
 662                                COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 0);
 663                cobalt_s_bit_sysctrl(cobalt,
 664                                COBALT_SYS_CTRL_VIDEO_TX_RESETN_BIT, 1);
 665                cobalt->have_hsma_tx = true;
 666                v4l2_subdev_call(s->sd, core, s_power, 1);
 667                v4l2_subdev_call(s->sd, video, s_stream, 1);
 668                v4l2_subdev_call(s->sd, audio, s_stream, 1);
 669                v4l2_ctrl_s_ctrl(v4l2_ctrl_find(s->sd->ctrl_handler,
 670                                 V4L2_CID_DV_TX_MODE), V4L2_DV_TX_MODE_HDMI);
 671                s->is_dummy = false;
 672                cobalt->streams[COBALT_AUDIO_OUT_STREAM].is_dummy = false;
 673                return 0;
 674        }
 675        return -ENODEV;
 676}
 677
 678static int cobalt_probe(struct pci_dev *pci_dev,
 679                                  const struct pci_device_id *pci_id)
 680{
 681        struct cobalt *cobalt;
 682        int retval = 0;
 683        int i;
 684
 685        /* FIXME - module parameter arrays constrain max instances */
 686        i = atomic_inc_return(&cobalt_instance) - 1;
 687
 688        cobalt = kzalloc(sizeof(struct cobalt), GFP_ATOMIC);
 689        if (cobalt == NULL)
 690                return -ENOMEM;
 691        cobalt->pci_dev = pci_dev;
 692        cobalt->instance = i;
 693
 694        cobalt->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev);
 695        if (IS_ERR(cobalt->alloc_ctx)) {
 696                kfree(cobalt);
 697                return -ENOMEM;
 698        }
 699
 700        retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev);
 701        if (retval) {
 702                pr_err("cobalt: v4l2_device_register of card %d failed\n",
 703                                cobalt->instance);
 704                vb2_dma_sg_cleanup_ctx(cobalt->alloc_ctx);
 705                kfree(cobalt);
 706                return retval;
 707        }
 708        snprintf(cobalt->v4l2_dev.name, sizeof(cobalt->v4l2_dev.name),
 709                 "cobalt-%d", cobalt->instance);
 710        cobalt->v4l2_dev.notify = cobalt_notify;
 711        cobalt_info("Initializing card %d\n", cobalt->instance);
 712
 713        cobalt->irq_work_queues =
 714                create_singlethread_workqueue(cobalt->v4l2_dev.name);
 715        if (cobalt->irq_work_queues == NULL) {
 716                cobalt_err("Could not create workqueue\n");
 717                retval = -ENOMEM;
 718                goto err;
 719        }
 720
 721        INIT_WORK(&cobalt->irq_work_queue, cobalt_irq_work_handler);
 722
 723        /* PCI Device Setup */
 724        retval = cobalt_setup_pci(cobalt, pci_dev, pci_id);
 725        if (retval != 0)
 726                goto err_wq;
 727
 728        /* Show HDL version info */
 729        if (cobalt_hdl_info_get(cobalt))
 730                cobalt_info("Not able to read the HDL info\n");
 731        else
 732                cobalt_info("%s", cobalt->hdl_info);
 733
 734        retval = cobalt_i2c_init(cobalt);
 735        if (retval)
 736                goto err_pci;
 737
 738        cobalt_stream_struct_init(cobalt);
 739
 740        retval = cobalt_subdevs_init(cobalt);
 741        if (retval)
 742                goto err_i2c;
 743
 744        if (!(cobalt_read_bar1(cobalt, COBALT_SYS_STAT_BASE) &
 745                        COBALT_SYSSTAT_HSMA_PRSNTN_MSK)) {
 746                retval = cobalt_subdevs_hsma_init(cobalt);
 747                if (retval)
 748                        goto err_i2c;
 749        }
 750
 751        retval = v4l2_device_register_subdev_nodes(&cobalt->v4l2_dev);
 752        if (retval)
 753                goto err_i2c;
 754        retval = cobalt_nodes_register(cobalt);
 755        if (retval) {
 756                cobalt_err("Error %d registering device nodes\n", retval);
 757                goto err_i2c;
 758        }
 759        cobalt_set_interrupt(cobalt, true);
 760        v4l2_device_call_all(&cobalt->v4l2_dev, 0, core,
 761                                        interrupt_service_routine, 0, NULL);
 762
 763        cobalt_info("Initialized cobalt card\n");
 764
 765        cobalt_flash_probe(cobalt);
 766
 767        return 0;
 768
 769err_i2c:
 770        cobalt_i2c_exit(cobalt);
 771        cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 0);
 772err_pci:
 773        cobalt_free_msi(cobalt, pci_dev);
 774        cobalt_pci_iounmap(cobalt, pci_dev);
 775        pci_release_regions(cobalt->pci_dev);
 776        pci_disable_device(cobalt->pci_dev);
 777err_wq:
 778        destroy_workqueue(cobalt->irq_work_queues);
 779err:
 780        if (retval == 0)
 781                retval = -ENODEV;
 782        cobalt_err("error %d on initialization\n", retval);
 783
 784        v4l2_device_unregister(&cobalt->v4l2_dev);
 785        vb2_dma_sg_cleanup_ctx(cobalt->alloc_ctx);
 786        kfree(cobalt);
 787        return retval;
 788}
 789
 790static void cobalt_remove(struct pci_dev *pci_dev)
 791{
 792        struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
 793        struct cobalt *cobalt = to_cobalt(v4l2_dev);
 794        int i;
 795
 796        cobalt_flash_remove(cobalt);
 797        cobalt_set_interrupt(cobalt, false);
 798        flush_workqueue(cobalt->irq_work_queues);
 799        cobalt_nodes_unregister(cobalt);
 800        for (i = 0; i < COBALT_NUM_ADAPTERS; i++) {
 801                struct v4l2_subdev *sd = cobalt->streams[i].sd;
 802                struct i2c_client *client;
 803
 804                if (sd == NULL)
 805                        continue;
 806                client = v4l2_get_subdevdata(sd);
 807                v4l2_device_unregister_subdev(sd);
 808                i2c_unregister_device(client);
 809        }
 810        cobalt_i2c_exit(cobalt);
 811        cobalt_free_msi(cobalt, pci_dev);
 812        cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 0);
 813        cobalt_pci_iounmap(cobalt, pci_dev);
 814        pci_release_regions(cobalt->pci_dev);
 815        pci_disable_device(cobalt->pci_dev);
 816        destroy_workqueue(cobalt->irq_work_queues);
 817
 818        cobalt_info("removed cobalt card\n");
 819
 820        v4l2_device_unregister(v4l2_dev);
 821        vb2_dma_sg_cleanup_ctx(cobalt->alloc_ctx);
 822        kfree(cobalt);
 823}
 824
 825/* define a pci_driver for card detection */
 826static struct pci_driver cobalt_pci_driver = {
 827        .name =     "cobalt",
 828        .id_table = cobalt_pci_tbl,
 829        .probe =    cobalt_probe,
 830        .remove =   cobalt_remove,
 831};
 832
 833module_pci_driver(cobalt_pci_driver);
 834