]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/video/saa7164/saa7164-api.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[net-next-2.6.git] / drivers / media / video / saa7164 / saa7164-api.c
CommitLineData
443c1228
ST
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
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.
10 *
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
14 *
15 * GNU General Public License for more details.
16 *
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.
20 */
21
22#include <linux/wait.h>
5a0e3ad6 23#include <linux/slab.h>
443c1228
ST
24
25#include "saa7164.h"
26
27int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode)
28{
29 int ret;
30
31 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
32 SAA_STATE_CONTROL, sizeof(mode), &mode);
33 if (ret != SAA_OK)
34 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
35
36 return ret;
37}
38
39int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
40{
41 int ret;
42
43 ret = saa7164_cmd_send(dev, 0, GET_CUR,
44 GET_FW_VERSION_CONTROL, sizeof(u32), version);
45 if (ret != SAA_OK)
46 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
47
48 return ret;
49}
50
51int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
52{
53 u8 reg[] = { 0x0f, 0x00 };
54
55 if (buflen < 128)
56 return -ENOMEM;
57
58 /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
59 /* TODO: Pull the details from the boards struct */
60 return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
61 &reg[0], 128, buf);
62}
63
443c1228
ST
64
65int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
66 struct saa7164_tsport *port,
67 tmComResTSFormatDescrHeader_t *tsfmt)
68{
69 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
70 dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
71 dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
72 dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
73 dprintk(DBGLVL_API, " bguid = (....)\n");
74
75 /* Cache the hardware configuration in the port */
76
77 port->bufcounter = port->hwcfg.BARLocation;
78 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
79 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
80 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
81 port->bufptr32l = port->hwcfg.BARLocation +
82 (4 * sizeof(u32)) +
83 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
84 port->bufptr32h = port->hwcfg.BARLocation +
85 (4 * sizeof(u32)) +
86 (sizeof(u32) * port->hwcfg.buffercount);
87 port->bufptr64 = port->hwcfg.BARLocation +
88 (4 * sizeof(u32)) +
89 (sizeof(u32) * port->hwcfg.buffercount);
90 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
91 port->hwcfg.BARLocation);
92
93 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
94 port->nr);
95
96 return 0;
97}
98
99int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
100{
101 struct saa7164_tsport *port = 0;
102 u32 idx, next_offset;
103 int i;
104 tmComResDescrHeader_t *hdr, *t;
105 tmComResExtDevDescrHeader_t *exthdr;
106 tmComResPathDescrHeader_t *pathhdr;
107 tmComResAntTermDescrHeader_t *anttermhdr;
108 tmComResTunerDescrHeader_t *tunerunithdr;
109 tmComResDMATermDescrHeader_t *vcoutputtermhdr;
110 tmComResTSFormatDescrHeader_t *tsfmt;
111 u32 currpath = 0;
112
113 dprintk(DBGLVL_API,
207b42c4
ST
114 "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
115 __func__, len, (u32)sizeof(tmComResDescrHeader_t));
443c1228
ST
116
117 for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
118
119 hdr = (tmComResDescrHeader_t *)(buf + idx);
120
121 if (hdr->type != CS_INTERFACE)
122 return SAA_ERR_NOT_SUPPORTED;
123
124 dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
125 switch (hdr->subtype) {
126 case GENERAL_REQUEST:
127 dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
128 break;
129 case VC_TUNER_PATH:
130 dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
131 pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
132 dprintk(DBGLVL_API, " pathid = 0x%x\n",
133 pathhdr->pathid);
134 currpath = pathhdr->pathid;
135 break;
136 case VC_INPUT_TERMINAL:
137 dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
138 anttermhdr =
139 (tmComResAntTermDescrHeader_t *)(buf + idx);
140 dprintk(DBGLVL_API, " terminalid = 0x%x\n",
141 anttermhdr->terminalid);
142 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
143 anttermhdr->terminaltype);
144 switch (anttermhdr->terminaltype) {
145 case ITT_ANTENNA:
146 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
147 break;
148 case LINE_CONNECTOR:
149 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
150 break;
151 case SPDIF_CONNECTOR:
152 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
153 break;
154 case COMPOSITE_CONNECTOR:
155 dprintk(DBGLVL_API,
156 " = COMPOSITE_CONNECTOR\n");
157 break;
158 case SVIDEO_CONNECTOR:
159 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
160 break;
161 case COMPONENT_CONNECTOR:
162 dprintk(DBGLVL_API,
163 " = COMPONENT_CONNECTOR\n");
164 break;
165 case STANDARD_DMA:
166 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
167 break;
168 default:
169 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
170 anttermhdr->terminaltype);
171 }
172 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
173 anttermhdr->assocterminal);
174 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
175 anttermhdr->iterminal);
176 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
177 anttermhdr->controlsize);
178 break;
179 case VC_OUTPUT_TERMINAL:
180 dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
181 vcoutputtermhdr =
182 (tmComResDMATermDescrHeader_t *)(buf + idx);
183 dprintk(DBGLVL_API, " unitid = 0x%x\n",
184 vcoutputtermhdr->unitid);
185 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
186 vcoutputtermhdr->terminaltype);
187 switch (vcoutputtermhdr->terminaltype) {
188 case ITT_ANTENNA:
189 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
190 break;
191 case LINE_CONNECTOR:
192 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
193 break;
194 case SPDIF_CONNECTOR:
195 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
196 break;
197 case COMPOSITE_CONNECTOR:
198 dprintk(DBGLVL_API,
199 " = COMPOSITE_CONNECTOR\n");
200 break;
201 case SVIDEO_CONNECTOR:
202 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
203 break;
204 case COMPONENT_CONNECTOR:
205 dprintk(DBGLVL_API,
206 " = COMPONENT_CONNECTOR\n");
207 break;
208 case STANDARD_DMA:
209 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
210 break;
211 default:
212 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
213 vcoutputtermhdr->terminaltype);
214 }
215 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
216 vcoutputtermhdr->assocterminal);
217 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
218 vcoutputtermhdr->sourceid);
219 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
220 vcoutputtermhdr->iterminal);
221 dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
222 vcoutputtermhdr->BARLocation);
223 dprintk(DBGLVL_API, " flags = 0x%x\n",
224 vcoutputtermhdr->flags);
225 dprintk(DBGLVL_API, " interruptid = 0x%x\n",
226 vcoutputtermhdr->interruptid);
227 dprintk(DBGLVL_API, " buffercount = 0x%x\n",
228 vcoutputtermhdr->buffercount);
229 dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
230 vcoutputtermhdr->metadatasize);
231 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
232 vcoutputtermhdr->controlsize);
233 dprintk(DBGLVL_API, " numformats = 0x%x\n",
234 vcoutputtermhdr->numformats);
235
236 t = (tmComResDescrHeader_t *)
237 ((tmComResDMATermDescrHeader_t *)(buf + idx));
238 next_offset = idx + (vcoutputtermhdr->len);
239 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
240 t = (tmComResDescrHeader_t *)
241 (buf + next_offset);
242 switch (t->subtype) {
243 case VS_FORMAT_MPEG2TS:
244 tsfmt =
245 (tmComResTSFormatDescrHeader_t *)t;
246 if (currpath == 1)
247 port = &dev->ts1;
248 else
249 port = &dev->ts2;
250 memcpy(&port->hwcfg, vcoutputtermhdr,
251 sizeof(*vcoutputtermhdr));
252 saa7164_api_configure_port_mpeg2ts(dev,
253 port, tsfmt);
254 break;
255 case VS_FORMAT_MPEG2PS:
256 dprintk(DBGLVL_API,
257 " = VS_FORMAT_MPEG2PS\n");
258 break;
259 case VS_FORMAT_VBI:
260 dprintk(DBGLVL_API,
261 " = VS_FORMAT_VBI\n");
262 break;
263 case VS_FORMAT_RDS:
264 dprintk(DBGLVL_API,
265 " = VS_FORMAT_RDS\n");
266 break;
267 case VS_FORMAT_UNCOMPRESSED:
268 dprintk(DBGLVL_API,
269 " = VS_FORMAT_UNCOMPRESSED\n");
270 break;
271 case VS_FORMAT_TYPE:
272 dprintk(DBGLVL_API,
273 " = VS_FORMAT_TYPE\n");
274 break;
275 default:
276 dprintk(DBGLVL_API,
277 " = undefined (0x%x)\n",
278 t->subtype);
279 }
280 next_offset += t->len;
281 }
282
283 break;
284 case TUNER_UNIT:
285 dprintk(DBGLVL_API, " TUNER_UNIT\n");
286 tunerunithdr =
287 (tmComResTunerDescrHeader_t *)(buf + idx);
288 dprintk(DBGLVL_API, " unitid = 0x%x\n",
289 tunerunithdr->unitid);
290 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
291 tunerunithdr->sourceid);
292 dprintk(DBGLVL_API, " iunit = 0x%x\n",
293 tunerunithdr->iunit);
294 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
295 tunerunithdr->tuningstandards);
296 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
297 tunerunithdr->controlsize);
298 dprintk(DBGLVL_API, " controls = 0x%x\n",
299 tunerunithdr->controls);
300 break;
301 case VC_SELECTOR_UNIT:
302 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
303 break;
304 case VC_PROCESSING_UNIT:
305 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
306 break;
307 case FEATURE_UNIT:
308 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
309 break;
310 case ENCODER_UNIT:
311 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
312 break;
313 case EXTENSION_UNIT:
314 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
315 exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
316 dprintk(DBGLVL_API, " unitid = 0x%x\n",
317 exthdr->unitid);
318 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
319 exthdr->deviceid);
320 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
321 exthdr->devicetype);
322 if (exthdr->devicetype & 0x1)
323 dprintk(DBGLVL_API, " = Decoder Device\n");
324 if (exthdr->devicetype & 0x2)
325 dprintk(DBGLVL_API, " = GPIO Source\n");
326 if (exthdr->devicetype & 0x4)
327 dprintk(DBGLVL_API, " = Video Decoder\n");
328 if (exthdr->devicetype & 0x8)
329 dprintk(DBGLVL_API, " = Audio Decoder\n");
330 if (exthdr->devicetype & 0x20)
331 dprintk(DBGLVL_API, " = Crossbar\n");
332 if (exthdr->devicetype & 0x40)
333 dprintk(DBGLVL_API, " = Tuner\n");
334 if (exthdr->devicetype & 0x80)
335 dprintk(DBGLVL_API, " = IF PLL\n");
336 if (exthdr->devicetype & 0x100)
337 dprintk(DBGLVL_API, " = Demodulator\n");
338 if (exthdr->devicetype & 0x200)
339 dprintk(DBGLVL_API, " = RDS Decoder\n");
340 if (exthdr->devicetype & 0x400)
341 dprintk(DBGLVL_API, " = Encoder\n");
342 if (exthdr->devicetype & 0x800)
343 dprintk(DBGLVL_API, " = IR Decoder\n");
344 if (exthdr->devicetype & 0x1000)
345 dprintk(DBGLVL_API, " = EEPROM\n");
346 if (exthdr->devicetype & 0x2000)
347 dprintk(DBGLVL_API,
348 " = VBI Decoder\n");
349 if (exthdr->devicetype & 0x10000)
350 dprintk(DBGLVL_API,
351 " = Streaming Device\n");
352 if (exthdr->devicetype & 0x20000)
353 dprintk(DBGLVL_API,
354 " = DRM Device\n");
355 if (exthdr->devicetype & 0x40000000)
356 dprintk(DBGLVL_API,
357 " = Generic Device\n");
358 if (exthdr->devicetype & 0x80000000)
359 dprintk(DBGLVL_API,
360 " = Config Space Device\n");
361 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
362 exthdr->numgpiopins);
363 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
364 exthdr->numgpiogroups);
365 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
366 exthdr->controlsize);
367 break;
368 case PVC_INFRARED_UNIT:
369 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
370 break;
371 case DRM_UNIT:
372 dprintk(DBGLVL_API, " DRM_UNIT\n");
373 break;
374 default:
375 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
376 }
377
378 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
379 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
380 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
381 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
382
383 idx += hdr->len;
384 }
385
386 return 0;
387}
388
389int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
390{
391 int ret;
392 u32 buflen = 0;
393 u8 *buf;
394
395 dprintk(DBGLVL_API, "%s()\n", __func__);
396
397 /* Get the total descriptor length */
398 ret = saa7164_cmd_send(dev, 0, GET_LEN,
399 GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
400 if (ret != SAA_OK)
401 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
402
403 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
404 __func__, buflen);
405
406 /* Allocate enough storage for all of the descs */
407 buf = kzalloc(buflen, GFP_KERNEL);
408 if (buf == NULL)
409 return SAA_ERR_NO_RESOURCES;
410
411 /* Retrieve them */
412 ret = saa7164_cmd_send(dev, 0, GET_CUR,
413 GET_DESCRIPTORS_CONTROL, buflen, buf);
414 if (ret != SAA_OK) {
415 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
416 goto out;
417 }
418
b1912a85 419 if (saa_debug & DBGLVL_API)
443c1228
ST
420 saa7164_dumphex16(dev, buf, (buflen/16)*16);
421
422 saa7164_api_dump_subdevs(dev, buf, buflen);
423
424out:
425 kfree(buf);
426 return ret;
427}
428
429int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
430 u32 datalen, u8 *data)
431{
432 struct saa7164_dev *dev = bus->dev;
433 u16 len = 0;
434 int unitid;
435 u32 regval;
436 u8 buf[256];
437 int ret;
438
439 dprintk(DBGLVL_API, "%s()\n", __func__);
440
441 if (reglen > 4)
442 return -EIO;
443
444 if (reglen == 1)
445 regval = *(reg);
446 else
447 if (reglen == 2)
448 regval = ((*(reg) << 8) || *(reg+1));
449 else
450 if (reglen == 3)
451 regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
452 else
453 if (reglen == 4)
454 regval = ((*(reg) << 24) | (*(reg+1) << 16) |
455 (*(reg+2) << 8) | *(reg+3));
456
457 /* Prepare the send buffer */
458 /* Bytes 00-03 source register length
459 * 04-07 source bytes to read
460 * 08... register address
461 */
462 memset(buf, 0, sizeof(buf));
463 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
464 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
465 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
466
467 unitid = saa7164_i2caddr_to_unitid(bus, addr);
468 if (unitid < 0) {
469 printk(KERN_ERR
470 "%s() error, cannot translate regaddr 0x%x to unitid\n",
471 __func__, addr);
472 return -EIO;
473 }
474
475 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
476 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
477 if (ret != SAA_OK) {
478 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
479 return -EIO;
480 }
481
482 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
483
b1912a85 484 if (saa_debug & DBGLVL_I2C)
443c1228
ST
485 saa7164_dumphex16(dev, buf, 2 * 16);
486
487 ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
488 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
489 if (ret != SAA_OK)
490 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
491 else {
b1912a85 492 if (saa_debug & DBGLVL_I2C)
443c1228
ST
493 saa7164_dumphex16(dev, buf, sizeof(buf));
494 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
495 }
496
497 return ret == SAA_OK ? 0 : -EIO;
498}
499
500/* For a given 8 bit i2c address device, write the buffer */
501int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
502 u8 *data)
503{
504 struct saa7164_dev *dev = bus->dev;
505 u16 len = 0;
506 int unitid;
507 int reglen;
508 u8 buf[256];
509 int ret;
510
511 dprintk(DBGLVL_API, "%s()\n", __func__);
512
513 if ((datalen == 0) || (datalen > 232))
514 return -EIO;
515
516 memset(buf, 0, sizeof(buf));
517
518 unitid = saa7164_i2caddr_to_unitid(bus, addr);
519 if (unitid < 0) {
520 printk(KERN_ERR
521 "%s() error, cannot translate regaddr 0x%x to unitid\n",
522 __func__, addr);
523 return -EIO;
524 }
525
526 reglen = saa7164_i2caddr_to_reglen(bus, addr);
ad695510 527 if (reglen < 0) {
443c1228
ST
528 printk(KERN_ERR
529 "%s() error, cannot translate regaddr to reglen\n",
530 __func__);
531 return -EIO;
532 }
533
534 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
535 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
536 if (ret != SAA_OK) {
537 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
538 return -EIO;
539 }
540
541 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
542
543 /* Prepare the send buffer */
544 /* Bytes 00-03 dest register length
545 * 04-07 dest bytes to write
546 * 08... register address
547 */
548 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
549 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
550 memcpy((buf + 2 * sizeof(u32)), data, datalen);
551
b1912a85 552 if (saa_debug & DBGLVL_I2C)
443c1228
ST
553 saa7164_dumphex16(dev, buf, sizeof(buf));
554
555 ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
556 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
557 if (ret != SAA_OK)
558 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
559
560 return ret == SAA_OK ? 0 : -EIO;
561}
562
563
564int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
565 u8 pin, u8 state)
566{
567 int ret;
568 tmComResGPIO_t t;
569
570 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
571 __func__, unitid, pin, state);
572
573 if ((pin > 7) || (state > 2))
574 return SAA_ERR_BAD_PARAMETER;
575
576 t.pin = pin;
577 t.state = state;
578
579 ret = saa7164_cmd_send(dev, unitid, SET_CUR,
580 EXU_GPIO_CONTROL, sizeof(t), &t);
581 if (ret != SAA_OK)
582 printk(KERN_ERR "%s() error, ret = 0x%x\n",
583 __func__, ret);
584
585 return ret;
586}
587
588int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
589 u8 pin)
590{
591 return saa7164_api_modify_gpio(dev, unitid, pin, 1);
592}
593
594int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
595 u8 pin)
596{
597 return saa7164_api_modify_gpio(dev, unitid, pin, 0);
598}
599
600
601