2 * Driver for the NXP SAA7164 PCIe bridge
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define DRIVER_NAME "saa7164"
30 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
32 /* addr is in the card struct, get it from there */
33 static struct tda10048_config hauppauge_hvr2200_1_config = {
34 .demod_address = 0x10 >> 1,
35 .output_mode = TDA10048_SERIAL_OUTPUT,
36 .fwbulkwritelen = TDA10048_BULKWRITE_200,
37 .inversion = TDA10048_INVERSION_ON
39 static struct tda10048_config hauppauge_hvr2200_2_config = {
40 .demod_address = 0x12 >> 1,
41 .output_mode = TDA10048_SERIAL_OUTPUT,
42 .fwbulkwritelen = TDA10048_BULKWRITE_200,
43 .inversion = TDA10048_INVERSION_ON
46 static struct tda18271_std_map hauppauge_tda18271_std_map = {
47 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
48 .if_lvl = 6, .rfagc_top = 0x37 },
49 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
50 .if_lvl = 6, .rfagc_top = 0x37 },
53 static struct tda18271_config hauppauge_hvr22x0_tuner_config = {
54 .std_map = &hauppauge_tda18271_std_map,
55 .gate = TDA18271_GATE_ANALOG,
58 static struct s5h1411_config hauppauge_s5h1411_config = {
59 .output_mode = S5H1411_SERIAL_OUTPUT,
60 .gpio = S5H1411_GPIO_ON,
61 .qam_if = S5H1411_IF_4000,
62 .vsb_if = S5H1411_IF_3250,
63 .inversion = S5H1411_INVERSION_ON,
64 .status_mode = S5H1411_DEMODLOCKING,
65 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
68 static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port)
70 struct saa7164_dev *dev = port->dev;
73 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
74 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
75 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
79 dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__);
86 static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port)
88 struct saa7164_dev *dev = port->dev;
91 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
92 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
93 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
97 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
104 static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port)
106 struct saa7164_dev *dev = port->dev;
109 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
110 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
111 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
115 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
122 /* Firmware is very windows centric, meaning you have to transition
123 * the part through AVStream / KS Windows stages, forwards or backwards.
124 * States are: stopped, acquired (h/w), paused, started.
126 static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port)
128 struct saa7164_dev *dev = port->dev;
131 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
133 ret = saa7164_dvb_pause_tsport(port);
134 ret = saa7164_dvb_acquire_tsport(port);
135 ret = saa7164_dvb_stop_tsport(port);
140 static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port)
142 tmHWStreamParameters_t *params = &port->hw_streamingparams;
143 struct saa7164_dev *dev = port->dev;
144 struct saa7164_buffer *buf;
145 struct list_head *c, *n;
148 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
150 saa7164_writel(port->pitch, params->pitch);
151 saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
153 dprintk(DBGLVL_DVB, " configured:\n");
154 dprintk(DBGLVL_DVB, " lmmio 0x%llx\n", (u64)dev->lmmio);
155 dprintk(DBGLVL_DVB, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
156 saa7164_readl(port->bufcounter));
158 dprintk(DBGLVL_DVB, " pitch 0x%x = %d\n", port->pitch,
159 saa7164_readl(port->pitch));
161 dprintk(DBGLVL_DVB, " bufsize 0x%x = %d\n", port->bufsize,
162 saa7164_readl(port->bufsize));
164 dprintk(DBGLVL_DVB, " buffercount = %d\n", port->hwcfg.buffercount);
165 dprintk(DBGLVL_DVB, " bufoffset = 0x%x\n", port->bufoffset);
166 dprintk(DBGLVL_DVB, " bufptr32h = 0x%x\n", port->bufptr32h);
167 dprintk(DBGLVL_DVB, " bufptr32l = 0x%x\n", port->bufptr32l);
169 /* Poke the buffers and offsets into PCI space */
170 mutex_lock(&port->dmaqueue_lock);
171 list_for_each_safe(c, n, &port->dmaqueue.list) {
172 buf = list_entry(c, struct saa7164_buffer, list);
174 /* TODO: Review this in light of 32v64 assignments */
175 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
176 saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i),
178 saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
181 " buf[%d] offset 0x%lx (0x%x) "
182 "buf 0x%lx/%lx (0x%x/%x)\n",
184 port->bufoffset + (i * sizeof(u32)),
185 saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
186 port->bufptr32h + ((sizeof(u32) * 2) * i),
187 port->bufptr32l + ((sizeof(u32) * 2) * i),
188 saa7164_readl(port->bufptr32h + ((sizeof(u32) * i)
190 saa7164_readl(port->bufptr32l + ((sizeof(u32) * i)
193 if (i++ > port->hwcfg.buffercount)
197 mutex_unlock(&port->dmaqueue_lock);
202 static int saa7164_dvb_start_tsport(struct saa7164_tsport *port)
204 struct saa7164_dev *dev = port->dev;
207 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
209 saa7164_dvb_cfg_tsport(port);
211 /* Acquire the hardware */
212 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
213 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
214 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
217 /* Stop the hardware, regardless */
218 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
219 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
220 printk(KERN_ERR "%s() acquire/forced stop transition "
221 "failed, res = 0x%x\n", __func__, result);
226 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
228 /* Pause the hardware */
229 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
230 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
231 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
234 /* Stop the hardware, regardless */
235 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
236 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
237 printk(KERN_ERR "%s() pause/forced stop transition "
238 "failed, res = 0x%x\n", __func__, result);
244 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
246 /* Start the hardware */
247 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
248 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
249 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
252 /* Stop the hardware, regardless */
253 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
254 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
255 printk(KERN_ERR "%s() run/forced stop transition "
256 "failed, res = 0x%x\n", __func__, result);
261 dprintk(DBGLVL_DVB, "%s() Running\n", __func__);
267 static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
269 struct dvb_demux *demux = feed->demux;
270 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
271 struct saa7164_dvb *dvb = &port->dvb;
272 struct saa7164_dev *dev = port->dev;
275 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
277 if (!demux->dmx.frontend)
281 mutex_lock(&dvb->lock);
282 if (dvb->feeding++ == 0) {
283 /* Start transport */
284 ret = saa7164_dvb_start_tsport(port);
286 mutex_unlock(&dvb->lock);
287 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
288 __func__, port->nr, dvb->feeding);
294 static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
296 struct dvb_demux *demux = feed->demux;
297 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
298 struct saa7164_dvb *dvb = &port->dvb;
299 struct saa7164_dev *dev = port->dev;
302 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
305 mutex_lock(&dvb->lock);
306 if (--dvb->feeding == 0) {
308 ret = saa7164_dvb_stop_streaming(port);
310 mutex_unlock(&dvb->lock);
311 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
312 __func__, port->nr, dvb->feeding);
318 static int dvb_register(struct saa7164_tsport *port)
320 struct saa7164_dvb *dvb = &port->dvb;
321 struct saa7164_dev *dev = port->dev;
322 struct saa7164_buffer *buf;
325 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
327 /* Sanity check that the PCI configuration space is active */
328 if (port->hwcfg.BARLocation == 0) {
330 printk(KERN_ERR "%s: dvb_register_adapter failed "
331 "(errno = %d), NO PCI configuration\n",
332 DRIVER_NAME, result);
336 /* Init and establish defaults */
337 port->hw_streamingparams.bitspersample = 8;
338 port->hw_streamingparams.samplesperline = 188;
339 port->hw_streamingparams.numberoflines =
340 (SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
342 port->hw_streamingparams.pitch = 188;
343 port->hw_streamingparams.linethreshold = 0;
344 port->hw_streamingparams.pagetablelistvirt = 0;
345 port->hw_streamingparams.pagetablelistphys = 0;
346 port->hw_streamingparams.numpagetables = 2 +
347 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
349 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
351 /* Allocate the PCI resources */
352 for (i = 0; i < port->hwcfg.buffercount; i++) {
353 buf = saa7164_buffer_alloc(port,
354 port->hw_streamingparams.numberoflines *
355 port->hw_streamingparams.pitch);
359 printk(KERN_ERR "%s: dvb_register_adapter failed "
360 "(errno = %d), unable to allocate buffers\n",
361 DRIVER_NAME, result);
366 mutex_lock(&port->dmaqueue_lock);
367 list_add_tail(&buf->list, &port->dmaqueue.list);
368 mutex_unlock(&port->dmaqueue_lock);
371 /* register adapter */
372 result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
373 &dev->pci->dev, adapter_nr);
375 printk(KERN_ERR "%s: dvb_register_adapter failed "
376 "(errno = %d)\n", DRIVER_NAME, result);
379 dvb->adapter.priv = port;
381 /* register frontend */
382 result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
384 printk(KERN_ERR "%s: dvb_register_frontend failed "
385 "(errno = %d)\n", DRIVER_NAME, result);
389 /* register demux stuff */
390 dvb->demux.dmx.capabilities =
391 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
392 DMX_MEMORY_BASED_FILTERING;
393 dvb->demux.priv = port;
394 dvb->demux.filternum = 256;
395 dvb->demux.feednum = 256;
396 dvb->demux.start_feed = saa7164_dvb_start_feed;
397 dvb->demux.stop_feed = saa7164_dvb_stop_feed;
398 result = dvb_dmx_init(&dvb->demux);
400 printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
401 DRIVER_NAME, result);
405 dvb->dmxdev.filternum = 256;
406 dvb->dmxdev.demux = &dvb->demux.dmx;
407 dvb->dmxdev.capabilities = 0;
408 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
410 printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
411 DRIVER_NAME, result);
415 dvb->fe_hw.source = DMX_FRONTEND_0;
416 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
418 printk(KERN_ERR "%s: add_frontend failed "
419 "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
423 dvb->fe_mem.source = DMX_MEMORY_FE;
424 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
426 printk(KERN_ERR "%s: add_frontend failed "
427 "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
431 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
433 printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
434 DRIVER_NAME, result);
438 /* register network adapter */
439 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
443 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
445 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
447 dvb_dmxdev_release(&dvb->dmxdev);
449 dvb_dmx_release(&dvb->demux);
451 dvb_unregister_frontend(dvb->frontend);
453 dvb_frontend_detach(dvb->frontend);
454 dvb_unregister_adapter(&dvb->adapter);
459 int saa7164_dvb_unregister(struct saa7164_tsport *port)
461 struct saa7164_dvb *dvb = &port->dvb;
462 struct saa7164_dev *dev = port->dev;
463 struct saa7164_buffer *b;
464 struct list_head *c, *n;
466 dprintk(DBGLVL_DVB, "%s()\n", __func__);
468 /* Remove any allocated buffers */
469 mutex_lock(&port->dmaqueue_lock);
470 list_for_each_safe(c, n, &port->dmaqueue.list) {
471 b = list_entry(c, struct saa7164_buffer, list);
473 saa7164_buffer_dealloc(port, b);
475 mutex_unlock(&port->dmaqueue_lock);
477 if (dvb->frontend == NULL)
480 dvb_net_release(&dvb->net);
481 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
482 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
483 dvb_dmxdev_release(&dvb->dmxdev);
484 dvb_dmx_release(&dvb->demux);
485 dvb_unregister_frontend(dvb->frontend);
486 dvb_frontend_detach(dvb->frontend);
487 dvb_unregister_adapter(&dvb->adapter);
491 /* All the DVB attach calls go here, this function get's modified
494 int saa7164_dvb_register(struct saa7164_tsport *port)
496 struct saa7164_dev *dev = port->dev;
497 struct saa7164_dvb *dvb = &port->dvb;
498 struct saa7164_i2c *i2c_bus = NULL;
501 dprintk(DBGLVL_DVB, "%s()\n", __func__);
504 switch (dev->board) {
505 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
506 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
507 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
510 i2c_bus = &dev->i2c_bus[1];
512 port->dvb.frontend = dvb_attach(tda10048_attach,
513 &hauppauge_hvr2200_1_config,
516 if (port->dvb.frontend != NULL) {
517 dvb_attach(tda18271_attach, port->dvb.frontend,
518 0xc0 >> 1, &i2c_bus->i2c_adap,
519 &hauppauge_hvr22x0_tuner_config);
524 i2c_bus = &dev->i2c_bus[2];
526 port->dvb.frontend = dvb_attach(tda10048_attach,
527 &hauppauge_hvr2200_2_config,
530 if (port->dvb.frontend != NULL) {
531 dvb_attach(tda18271_attach, port->dvb.frontend,
532 0xc0 >> 1, &i2c_bus->i2c_adap,
533 &hauppauge_hvr22x0_tuner_config);
539 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
540 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
541 i2c_bus = &dev->i2c_bus[port->nr + 1];
543 port->dvb.frontend = dvb_attach(s5h1411_attach,
544 &hauppauge_s5h1411_config,
547 if (port->dvb.frontend != NULL) {
548 /* TODO: addr is in the card struct */
549 dvb_attach(tda18271_attach, port->dvb.frontend,
550 0xc0 >> 1, &i2c_bus->i2c_adap,
551 &hauppauge_hvr22x0_tuner_config);
556 printk(KERN_ERR "%s: The frontend isn't supported\n",
560 if (NULL == dvb->frontend) {
561 printk(KERN_ERR "%s() Frontend initialization failed\n",
566 /* Put the analog decoder in standby to keep it quiet */
568 /* register everything */
569 ret = dvb_register(port);
571 if (dvb->frontend->ops.release)
572 dvb->frontend->ops.release(dvb->frontend);