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.
22 #include <linux/wait.h>
26 int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode)
30 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
31 SAA_STATE_CONTROL, sizeof(mode), &mode);
33 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
38 int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
42 ret = saa7164_cmd_send(dev, 0, GET_CUR,
43 GET_FW_VERSION_CONTROL, sizeof(u32), version);
45 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
50 int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
52 u8 reg[] = { 0x0f, 0x00 };
57 /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
58 /* TODO: Pull the details from the boards struct */
59 return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
63 /* Exercise the i2c interface, saa7164_cmd()/bus() layers:
64 * 1. Read the identity byte from each of the demodulators.
65 * 2. Read the entire register set from the TDA18271.
66 * TODO: This function has no purpose other than to exercise i2c.
68 int saa7164_api_test(struct saa7164_dev *dev)
70 /* TDA10048 identities */
73 dprintk(DBGLVL_API, "%s()\n", __func__);
74 /* Read all 39 bytes from the TDA18271 tuners */
75 saa7164_api_i2c_read(&dev->i2c_bus[1], 0xc0 >> 1, 0,
76 ®[0], 39, &data[0]);
77 saa7164_api_i2c_read(&dev->i2c_bus[2], 0xc0 >> 1, 0,
78 ®[0], 39, &data[0]);
83 int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
84 struct saa7164_tsport *port,
85 tmComResTSFormatDescrHeader_t *tsfmt)
87 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
88 dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
89 dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
90 dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
91 dprintk(DBGLVL_API, " bguid = (....)\n");
93 /* Cache the hardware configuration in the port */
95 port->bufcounter = port->hwcfg.BARLocation;
96 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
97 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
98 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
99 port->bufptr32l = port->hwcfg.BARLocation +
101 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
102 port->bufptr32h = port->hwcfg.BARLocation +
104 (sizeof(u32) * port->hwcfg.buffercount);
105 port->bufptr64 = port->hwcfg.BARLocation +
107 (sizeof(u32) * port->hwcfg.buffercount);
108 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
109 port->hwcfg.BARLocation);
111 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
117 int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
119 struct saa7164_tsport *port = 0;
120 u32 idx, next_offset;
122 tmComResDescrHeader_t *hdr, *t;
123 tmComResExtDevDescrHeader_t *exthdr;
124 tmComResPathDescrHeader_t *pathhdr;
125 tmComResAntTermDescrHeader_t *anttermhdr;
126 tmComResTunerDescrHeader_t *tunerunithdr;
127 tmComResDMATermDescrHeader_t *vcoutputtermhdr;
128 tmComResTSFormatDescrHeader_t *tsfmt;
132 "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
133 __func__, len, (u32)sizeof(tmComResDescrHeader_t));
135 for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
137 hdr = (tmComResDescrHeader_t *)(buf + idx);
139 if (hdr->type != CS_INTERFACE)
140 return SAA_ERR_NOT_SUPPORTED;
142 dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
143 switch (hdr->subtype) {
144 case GENERAL_REQUEST:
145 dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
148 dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
149 pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
150 dprintk(DBGLVL_API, " pathid = 0x%x\n",
152 currpath = pathhdr->pathid;
154 case VC_INPUT_TERMINAL:
155 dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
157 (tmComResAntTermDescrHeader_t *)(buf + idx);
158 dprintk(DBGLVL_API, " terminalid = 0x%x\n",
159 anttermhdr->terminalid);
160 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
161 anttermhdr->terminaltype);
162 switch (anttermhdr->terminaltype) {
164 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
167 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
169 case SPDIF_CONNECTOR:
170 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
172 case COMPOSITE_CONNECTOR:
174 " = COMPOSITE_CONNECTOR\n");
176 case SVIDEO_CONNECTOR:
177 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
179 case COMPONENT_CONNECTOR:
181 " = COMPONENT_CONNECTOR\n");
184 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
187 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
188 anttermhdr->terminaltype);
190 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
191 anttermhdr->assocterminal);
192 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
193 anttermhdr->iterminal);
194 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
195 anttermhdr->controlsize);
197 case VC_OUTPUT_TERMINAL:
198 dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
200 (tmComResDMATermDescrHeader_t *)(buf + idx);
201 dprintk(DBGLVL_API, " unitid = 0x%x\n",
202 vcoutputtermhdr->unitid);
203 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
204 vcoutputtermhdr->terminaltype);
205 switch (vcoutputtermhdr->terminaltype) {
207 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
210 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
212 case SPDIF_CONNECTOR:
213 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
215 case COMPOSITE_CONNECTOR:
217 " = COMPOSITE_CONNECTOR\n");
219 case SVIDEO_CONNECTOR:
220 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
222 case COMPONENT_CONNECTOR:
224 " = COMPONENT_CONNECTOR\n");
227 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
230 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
231 vcoutputtermhdr->terminaltype);
233 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
234 vcoutputtermhdr->assocterminal);
235 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
236 vcoutputtermhdr->sourceid);
237 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
238 vcoutputtermhdr->iterminal);
239 dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
240 vcoutputtermhdr->BARLocation);
241 dprintk(DBGLVL_API, " flags = 0x%x\n",
242 vcoutputtermhdr->flags);
243 dprintk(DBGLVL_API, " interruptid = 0x%x\n",
244 vcoutputtermhdr->interruptid);
245 dprintk(DBGLVL_API, " buffercount = 0x%x\n",
246 vcoutputtermhdr->buffercount);
247 dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
248 vcoutputtermhdr->metadatasize);
249 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
250 vcoutputtermhdr->controlsize);
251 dprintk(DBGLVL_API, " numformats = 0x%x\n",
252 vcoutputtermhdr->numformats);
254 t = (tmComResDescrHeader_t *)
255 ((tmComResDMATermDescrHeader_t *)(buf + idx));
256 next_offset = idx + (vcoutputtermhdr->len);
257 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
258 t = (tmComResDescrHeader_t *)
260 switch (t->subtype) {
261 case VS_FORMAT_MPEG2TS:
263 (tmComResTSFormatDescrHeader_t *)t;
268 memcpy(&port->hwcfg, vcoutputtermhdr,
269 sizeof(*vcoutputtermhdr));
270 saa7164_api_configure_port_mpeg2ts(dev,
273 case VS_FORMAT_MPEG2PS:
275 " = VS_FORMAT_MPEG2PS\n");
279 " = VS_FORMAT_VBI\n");
283 " = VS_FORMAT_RDS\n");
285 case VS_FORMAT_UNCOMPRESSED:
287 " = VS_FORMAT_UNCOMPRESSED\n");
291 " = VS_FORMAT_TYPE\n");
295 " = undefined (0x%x)\n",
298 next_offset += t->len;
303 dprintk(DBGLVL_API, " TUNER_UNIT\n");
305 (tmComResTunerDescrHeader_t *)(buf + idx);
306 dprintk(DBGLVL_API, " unitid = 0x%x\n",
307 tunerunithdr->unitid);
308 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
309 tunerunithdr->sourceid);
310 dprintk(DBGLVL_API, " iunit = 0x%x\n",
311 tunerunithdr->iunit);
312 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
313 tunerunithdr->tuningstandards);
314 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
315 tunerunithdr->controlsize);
316 dprintk(DBGLVL_API, " controls = 0x%x\n",
317 tunerunithdr->controls);
319 case VC_SELECTOR_UNIT:
320 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
322 case VC_PROCESSING_UNIT:
323 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
326 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
329 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
332 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
333 exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
334 dprintk(DBGLVL_API, " unitid = 0x%x\n",
336 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
338 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
340 if (exthdr->devicetype & 0x1)
341 dprintk(DBGLVL_API, " = Decoder Device\n");
342 if (exthdr->devicetype & 0x2)
343 dprintk(DBGLVL_API, " = GPIO Source\n");
344 if (exthdr->devicetype & 0x4)
345 dprintk(DBGLVL_API, " = Video Decoder\n");
346 if (exthdr->devicetype & 0x8)
347 dprintk(DBGLVL_API, " = Audio Decoder\n");
348 if (exthdr->devicetype & 0x20)
349 dprintk(DBGLVL_API, " = Crossbar\n");
350 if (exthdr->devicetype & 0x40)
351 dprintk(DBGLVL_API, " = Tuner\n");
352 if (exthdr->devicetype & 0x80)
353 dprintk(DBGLVL_API, " = IF PLL\n");
354 if (exthdr->devicetype & 0x100)
355 dprintk(DBGLVL_API, " = Demodulator\n");
356 if (exthdr->devicetype & 0x200)
357 dprintk(DBGLVL_API, " = RDS Decoder\n");
358 if (exthdr->devicetype & 0x400)
359 dprintk(DBGLVL_API, " = Encoder\n");
360 if (exthdr->devicetype & 0x800)
361 dprintk(DBGLVL_API, " = IR Decoder\n");
362 if (exthdr->devicetype & 0x1000)
363 dprintk(DBGLVL_API, " = EEPROM\n");
364 if (exthdr->devicetype & 0x2000)
367 if (exthdr->devicetype & 0x10000)
369 " = Streaming Device\n");
370 if (exthdr->devicetype & 0x20000)
373 if (exthdr->devicetype & 0x40000000)
375 " = Generic Device\n");
376 if (exthdr->devicetype & 0x80000000)
378 " = Config Space Device\n");
379 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
380 exthdr->numgpiopins);
381 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
382 exthdr->numgpiogroups);
383 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
384 exthdr->controlsize);
386 case PVC_INFRARED_UNIT:
387 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
390 dprintk(DBGLVL_API, " DRM_UNIT\n");
393 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
396 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
397 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
398 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
399 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
407 int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
413 dprintk(DBGLVL_API, "%s()\n", __func__);
415 /* Get the total descriptor length */
416 ret = saa7164_cmd_send(dev, 0, GET_LEN,
417 GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
419 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
421 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
424 /* Allocate enough storage for all of the descs */
425 buf = kzalloc(buflen, GFP_KERNEL);
427 return SAA_ERR_NO_RESOURCES;
430 ret = saa7164_cmd_send(dev, 0, GET_CUR,
431 GET_DESCRIPTORS_CONTROL, buflen, buf);
433 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
437 if (debug & DBGLVL_API)
438 saa7164_dumphex16(dev, buf, (buflen/16)*16);
440 saa7164_api_dump_subdevs(dev, buf, buflen);
447 int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
448 u32 datalen, u8 *data)
450 struct saa7164_dev *dev = bus->dev;
457 dprintk(DBGLVL_API, "%s()\n", __func__);
466 regval = ((*(reg) << 8) || *(reg+1));
469 regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
472 regval = ((*(reg) << 24) | (*(reg+1) << 16) |
473 (*(reg+2) << 8) | *(reg+3));
475 /* Prepare the send buffer */
476 /* Bytes 00-03 source register length
477 * 04-07 source bytes to read
478 * 08... register address
480 memset(buf, 0, sizeof(buf));
481 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
482 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
483 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
485 unitid = saa7164_i2caddr_to_unitid(bus, addr);
488 "%s() error, cannot translate regaddr 0x%x to unitid\n",
493 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
494 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
496 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
500 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
502 if (debug & DBGLVL_I2C)
503 saa7164_dumphex16(dev, buf, 2 * 16);
505 ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
506 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
508 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
510 if (debug & DBGLVL_I2C)
511 saa7164_dumphex16(dev, buf, sizeof(buf));
512 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
515 return ret == SAA_OK ? 0 : -EIO;
518 /* For a given 8 bit i2c address device, write the buffer */
519 int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
522 struct saa7164_dev *dev = bus->dev;
529 dprintk(DBGLVL_API, "%s()\n", __func__);
531 if ((datalen == 0) || (datalen > 232))
534 memset(buf, 0, sizeof(buf));
536 unitid = saa7164_i2caddr_to_unitid(bus, addr);
539 "%s() error, cannot translate regaddr 0x%x to unitid\n",
544 reglen = saa7164_i2caddr_to_reglen(bus, addr);
547 "%s() error, cannot translate regaddr to reglen\n",
552 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
553 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
555 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
559 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
561 /* Prepare the send buffer */
562 /* Bytes 00-03 dest register length
563 * 04-07 dest bytes to write
564 * 08... register address
566 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
567 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
568 memcpy((buf + 2 * sizeof(u32)), data, datalen);
570 if (debug & DBGLVL_I2C)
571 saa7164_dumphex16(dev, buf, sizeof(buf));
573 ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
574 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
576 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
578 return ret == SAA_OK ? 0 : -EIO;
582 int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
588 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
589 __func__, unitid, pin, state);
591 if ((pin > 7) || (state > 2))
592 return SAA_ERR_BAD_PARAMETER;
597 ret = saa7164_cmd_send(dev, unitid, SET_CUR,
598 EXU_GPIO_CONTROL, sizeof(t), &t);
600 printk(KERN_ERR "%s() error, ret = 0x%x\n",
606 int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
609 return saa7164_api_modify_gpio(dev, unitid, pin, 1);
612 int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
615 return saa7164_api_modify_gpio(dev, unitid, pin, 0);