0001
0002
0003
0004
0005
0006
0007
0008
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
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
0113 cobalt_write_bar1(cobalt, COBALT_SYS_STAT_EDGE, 0xffffffff);
0114
0115
0116 cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, irqs);
0117 } else {
0118
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
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
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
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
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
0363 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE);
0364 cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, ctrl & ~0xf00);
0365
0366
0367
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
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
0428
0429
0430
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
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
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,
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
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
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
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
0695 retval = cobalt_setup_pci(cobalt, pci_dev, pci_id);
0696 if (retval != 0)
0697 goto err_wq;
0698
0699
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
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);