123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- /*
- * Handlers for board audio hooks, splitted from bttv-cards
- *
- * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org>
- * This code is placed under the terms of the GNU General Public License
- */
- #include "bttv-audio-hook.h"
- #include <linux/delay.h>
- /* ----------------------------------------------------------------------- */
- /* winview */
- void winview_volume(struct bttv *btv, __u16 volume)
- {
- /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
- int bits_out, loops, vol, data;
- /* 32 levels logarithmic */
- vol = 32 - ((volume>>11));
- /* units */
- bits_out = (PT2254_DBS_IN_2>>(vol%5));
- /* tens */
- bits_out |= (PT2254_DBS_IN_10>>(vol/5));
- bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
- data = gpio_read();
- data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
- WINVIEW_PT2254_STROBE);
- for (loops = 17; loops >= 0 ; loops--) {
- if (bits_out & (1<<loops))
- data |= WINVIEW_PT2254_DATA;
- else
- data &= ~WINVIEW_PT2254_DATA;
- gpio_write(data);
- udelay(5);
- data |= WINVIEW_PT2254_CLK;
- gpio_write(data);
- udelay(5);
- data &= ~WINVIEW_PT2254_CLK;
- gpio_write(data);
- }
- data |= WINVIEW_PT2254_STROBE;
- data &= ~WINVIEW_PT2254_DATA;
- gpio_write(data);
- udelay(10);
- data &= ~WINVIEW_PT2254_STROBE;
- gpio_write(data);
- }
- /* ----------------------------------------------------------------------- */
- /* mono/stereo control for various cards (which don't use i2c chips but */
- /* connect something to the GPIO pins */
- void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned int con;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- gpio_inout(0x300, 0x300);
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG1:
- default:
- con = 0x000;
- break;
- case V4L2_TUNER_MODE_LANG2:
- con = 0x300;
- break;
- case V4L2_TUNER_MODE_STEREO:
- con = 0x200;
- break;
- }
- gpio_bits(0x300, con);
- }
- void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned int val, con;
- if (btv->radio_user)
- return;
- val = gpio_read();
- if (set) {
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG2:
- con = 0x300;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- con = 0x100;
- break;
- default:
- con = 0x000;
- break;
- }
- if (con != (val & 0x300)) {
- gpio_bits(0x300, con);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "gvbctv5pci");
- }
- } else {
- switch (val & 0x70) {
- case 0x10:
- t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- t->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
- break;
- case 0x30:
- t->rxsubchans = V4L2_TUNER_SUB_LANG2;
- t->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
- break;
- case 0x50:
- t->rxsubchans = V4L2_TUNER_SUB_LANG1;
- t->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
- break;
- case 0x60:
- t->rxsubchans = V4L2_TUNER_SUB_STEREO;
- t->audmode = V4L2_TUNER_MODE_STEREO;
- break;
- case 0x70:
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
- t->audmode = V4L2_TUNER_MODE_MONO;
- break;
- default:
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- t->audmode = V4L2_TUNER_MODE_LANG1;
- }
- }
- }
- /*
- * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
- * I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
- * 0xdde enables mono and 0xccd enables sap
- *
- * Petr Vandrovec <VANDROVE@vc.cvut.cz>
- * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
- * input/output sound connection, so both must be set for output mode.
- *
- * Looks like it's needed only for the "tvphone", the "tvphone 98"
- * handles this with a tda9840
- *
- */
- void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- int val;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG2: /* SAP */
- val = 0x02;
- break;
- case V4L2_TUNER_MODE_STEREO:
- val = 0x01;
- break;
- default:
- return;
- }
- gpio_bits(0x03, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "avermedia");
- }
- void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- int val = 0;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG2: /* SAP */
- val = 0x01;
- break;
- case V4L2_TUNER_MODE_STEREO:
- val = 0x02;
- break;
- default:
- val = 0;
- break;
- }
- btaor(val, ~0x03, BT848_GPIO_DATA);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "avermedia");
- }
- /* Lifetec 9415 handling */
- void lt9415_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- int val = 0;
- if (gpio_read() & 0x4000) {
- t->audmode = V4L2_TUNER_MODE_MONO;
- return;
- }
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG2: /* A2 SAP */
- val = 0x0080;
- break;
- case V4L2_TUNER_MODE_STEREO: /* A2 stereo */
- val = 0x0880;
- break;
- default:
- val = 0;
- break;
- }
- gpio_bits(0x0880, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "lt9415");
- }
- /* TDA9821 on TerraTV+ Bt848, Bt878 */
- void terratv_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned int con = 0;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- gpio_inout(0x180000, 0x180000);
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG2:
- con = 0x080000;
- break;
- case V4L2_TUNER_MODE_STEREO:
- con = 0x180000;
- break;
- default:
- con = 0;
- break;
- }
- gpio_bits(0x180000, con);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "terratv");
- }
- void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned long val;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
- switch (t->audmode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- val = 0x420000;
- break;
- case V4L2_TUNER_MODE_LANG2: /* SAP */
- val = 0x410000;
- break;
- case V4L2_TUNER_MODE_STEREO:
- val = 0x020000;
- break;
- default:
- return;
- }
- gpio_bits(0x430000, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "winfast2000");
- }
- /*
- * Dariusz Kowalewski <darekk@automex.pl>
- * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
- * revision 9B has on-board TDA9874A sound decoder).
- *
- * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
- * will mute this cards.
- */
- void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned int val = 0;
- if (btv->radio_user)
- return;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- switch (t->audmode) {
- case V4L2_TUNER_MODE_MONO:
- val = 0x01;
- break;
- case V4L2_TUNER_MODE_LANG1:
- case V4L2_TUNER_MODE_LANG2:
- case V4L2_TUNER_MODE_STEREO:
- val = 0x02;
- break;
- default:
- return;
- }
- gpio_bits(0x03, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "pvbt878p9b");
- }
- /*
- * Dariusz Kowalewski <darekk@automex.pl>
- * sound control for FlyVideo 2000S (with tda9874 decoder)
- * based on pvbt878p9b_audio() - this is not tested, please fix!!!
- */
- void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned int val;
- if (btv->radio_user)
- return;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- switch (t->audmode) {
- case V4L2_TUNER_MODE_MONO:
- val = 0x0000;
- break;
- case V4L2_TUNER_MODE_LANG1:
- case V4L2_TUNER_MODE_LANG2:
- case V4L2_TUNER_MODE_STEREO:
- val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
- break;
- default:
- return;
- }
- gpio_bits(0x1800, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "fv2000s");
- }
- /*
- * sound control for Canopus WinDVR PCI
- * Masaki Suzuki <masaki@btree.org>
- */
- void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned long val;
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- switch (t->audmode) {
- case V4L2_TUNER_MODE_MONO:
- val = 0x040000;
- break;
- case V4L2_TUNER_MODE_LANG2:
- val = 0x100000;
- break;
- default:
- return;
- }
- gpio_bits(0x140000, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "windvr");
- }
- /*
- * sound control for AD-TVK503
- * Hiroshi Takekawa <sian@big.or.jp>
- */
- void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
- {
- unsigned int con = 0xffffff;
- /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
- if (!set) {
- /* Not much to do here */
- t->audmode = V4L2_TUNER_MODE_LANG1;
- t->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 |
- V4L2_TUNER_SUB_LANG2;
- return;
- }
- /* btor(***, BT848_GPIO_OUT_EN); */
- switch (t->audmode) {
- case V4L2_TUNER_MODE_LANG1:
- con = 0x00000000;
- break;
- case V4L2_TUNER_MODE_LANG2:
- con = 0x00180000;
- break;
- case V4L2_TUNER_MODE_STEREO:
- con = 0x00000000;
- break;
- case V4L2_TUNER_MODE_MONO:
- con = 0x00060000;
- break;
- default:
- return;
- }
- gpio_bits(0x1e0000, con);
- if (bttv_gpio)
- bttv_gpio_tracking(btv, "adtvk503");
- }
|