Blame view
sound/pcmcia/vx/vxpocket.c
8.49 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 |
/* * Driver for Digigram VXpocket V2/440 soundcards * * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de> |
1ac71e5a3 pcmcia: convert p... |
5 |
|
1da177e4c Linux-2.6.12-rc2 |
6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
1da177e4c Linux-2.6.12-rc2 |
20 |
|
1da177e4c Linux-2.6.12-rc2 |
21 |
#include <linux/init.h> |
65a772172 sound: fix driver... |
22 |
#include <linux/module.h> |
5a0e3ad6a include cleanup: ... |
23 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
24 |
#include <sound/core.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
#include "vxpocket.h" |
6d00a3127 [ALSA] Fix and cl... |
26 27 |
#include <pcmcia/ciscode.h> #include <pcmcia/cisreg.h> |
1da177e4c Linux-2.6.12-rc2 |
28 |
#include <sound/initval.h> |
1186ed8c7 [ALSA] Add dB sca... |
29 |
#include <sound/tlv.h> |
1da177e4c Linux-2.6.12-rc2 |
30 31 32 |
/* */ |
1da177e4c Linux-2.6.12-rc2 |
33 |
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
6d00a3127 [ALSA] Fix and cl... |
34 |
MODULE_DESCRIPTION("Digigram VXPocket"); |
1da177e4c Linux-2.6.12-rc2 |
35 |
MODULE_LICENSE("GPL"); |
6d00a3127 [ALSA] Fix and cl... |
36 |
MODULE_SUPPORTED_DEVICE("{{Digigram,VXPocket},{Digigram,VXPocket440}}"); |
1da177e4c Linux-2.6.12-rc2 |
37 38 39 |
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
a67ff6a54 ALSA: module_para... |
40 |
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 |
static int ibl[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); |
6d00a3127 [ALSA] Fix and cl... |
44 |
MODULE_PARM_DESC(index, "Index value for VXPocket soundcard."); |
1da177e4c Linux-2.6.12-rc2 |
45 |
module_param_array(id, charp, NULL, 0444); |
6d00a3127 [ALSA] Fix and cl... |
46 |
MODULE_PARM_DESC(id, "ID string for VXPocket soundcard."); |
1da177e4c Linux-2.6.12-rc2 |
47 |
module_param_array(enable, bool, NULL, 0444); |
6d00a3127 [ALSA] Fix and cl... |
48 |
MODULE_PARM_DESC(enable, "Enable VXPocket soundcard."); |
1da177e4c Linux-2.6.12-rc2 |
49 |
module_param_array(ibl, int, NULL, 0444); |
6d00a3127 [ALSA] Fix and cl... |
50 |
MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard."); |
1da177e4c Linux-2.6.12-rc2 |
51 52 53 54 |
/* */ |
6d00a3127 [ALSA] Fix and cl... |
55 |
static unsigned int card_alloc; |
1da177e4c Linux-2.6.12-rc2 |
56 |
|
1da177e4c Linux-2.6.12-rc2 |
57 |
|
6d00a3127 [ALSA] Fix and cl... |
58 59 |
/* */ |
fba395eee [PATCH] pcmcia: r... |
60 |
static void vxpocket_release(struct pcmcia_device *link) |
6d00a3127 [ALSA] Fix and cl... |
61 |
{ |
fba395eee [PATCH] pcmcia: r... |
62 |
pcmcia_disable_device(link); |
6d00a3127 [ALSA] Fix and cl... |
63 |
} |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
6d00a3127 [ALSA] Fix and cl... |
65 |
/* |
2b29b13c5 [ALSA] Deprecate ... |
66 |
* destructor, called from snd_card_free_when_closed() |
6d00a3127 [ALSA] Fix and cl... |
67 |
*/ |
af26367f6 [ALSA] Remove xxx... |
68 |
static int snd_vxpocket_dev_free(struct snd_device *device) |
6d00a3127 [ALSA] Fix and cl... |
69 |
{ |
af26367f6 [ALSA] Remove xxx... |
70 |
struct vx_core *chip = device->device_data; |
1da177e4c Linux-2.6.12-rc2 |
71 |
|
6d00a3127 [ALSA] Fix and cl... |
72 73 74 75 |
snd_vx_free_firmware(chip); kfree(chip); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
76 |
|
1da177e4c Linux-2.6.12-rc2 |
77 |
|
6d00a3127 [ALSA] Fix and cl... |
78 79 80 81 82 83 84 85 86 87 88 89 |
/* * Hardware information */ /* VX-pocket V2 * * 1 DSP, 1 sync UER * 1 programmable clock (NIY) * 1 stereo analog input (line/micro) * 1 stereo analog output * Only output levels can be modified */ |
0cb29ea0d [ALSA] Add even m... |
90 |
static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); |
1186ed8c7 [ALSA] Add dB sca... |
91 |
|
6d00a3127 [ALSA] Fix and cl... |
92 93 94 |
static struct snd_vx_hardware vxpocket_hw = { .name = "VXPocket", .type = VX_TYPE_VXPOCKET, |
1da177e4c Linux-2.6.12-rc2 |
95 96 |
/* hardware specs */ |
6d00a3127 [ALSA] Fix and cl... |
97 98 99 |
.num_codecs = 1, .num_ins = 1, .num_outs = 1, |
1da177e4c Linux-2.6.12-rc2 |
100 |
.output_level_max = VX_ANALOG_OUT_LEVEL_MAX, |
1186ed8c7 [ALSA] Add dB sca... |
101 |
.output_level_db_scale = db_scale_old_vol, |
1da177e4c Linux-2.6.12-rc2 |
102 |
}; |
6d00a3127 [ALSA] Fix and cl... |
103 104 105 106 107 108 109 110 111 |
/* VX-pocket 440 * * 1 DSP, 1 sync UER, 1 sync World Clock (NIY) * SMPTE (NIY) * 2 stereo analog input (line/micro) * 2 stereo analog output * Only output levels can be modified * UER, but only for the first two inputs and outputs. */ |
1da177e4c Linux-2.6.12-rc2 |
112 |
|
6d00a3127 [ALSA] Fix and cl... |
113 114 115 116 117 118 119 120 121 |
static struct snd_vx_hardware vxp440_hw = { .name = "VXPocket440", .type = VX_TYPE_VXP440, /* hardware specs */ .num_codecs = 2, .num_ins = 2, .num_outs = 2, .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, |
1186ed8c7 [ALSA] Add dB sca... |
122 |
.output_level_db_scale = db_scale_old_vol, |
6d00a3127 [ALSA] Fix and cl... |
123 124 125 126 127 128 |
}; /* * create vxpocket instance */ |
2fa51107c ALSA: Return prop... |
129 130 131 |
static int snd_vxpocket_new(struct snd_card *card, int ibl, struct pcmcia_device *link, struct snd_vxpocket **chip_ret) |
6d00a3127 [ALSA] Fix and cl... |
132 |
{ |
af26367f6 [ALSA] Remove xxx... |
133 |
struct vx_core *chip; |
6d00a3127 [ALSA] Fix and cl... |
134 |
struct snd_vxpocket *vxp; |
af26367f6 [ALSA] Remove xxx... |
135 |
static struct snd_device_ops ops = { |
6d00a3127 [ALSA] Fix and cl... |
136 137 |
.dev_free = snd_vxpocket_dev_free, }; |
2fa51107c ALSA: Return prop... |
138 |
int err; |
6d00a3127 [ALSA] Fix and cl... |
139 140 |
chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops, |
af26367f6 [ALSA] Remove xxx... |
141 |
sizeof(struct snd_vxpocket) - sizeof(struct vx_core)); |
2fa51107c ALSA: Return prop... |
142 143 |
if (!chip) return -ENOMEM; |
6d00a3127 [ALSA] Fix and cl... |
144 |
|
2fa51107c ALSA: Return prop... |
145 146 |
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { |
6d00a3127 [ALSA] Fix and cl... |
147 |
kfree(chip); |
2fa51107c ALSA: Return prop... |
148 |
return err; |
6d00a3127 [ALSA] Fix and cl... |
149 150 151 152 |
} chip->ibl.size = ibl; vxp = (struct snd_vxpocket *)chip; |
fba395eee [PATCH] pcmcia: r... |
153 |
vxp->p_dev = link; |
6d00a3127 [ALSA] Fix and cl... |
154 |
link->priv = chip; |
90abdc3b9 pcmcia: do not us... |
155 156 |
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->resource[0]->end = 16; |
6d00a3127 [ALSA] Fix and cl... |
157 |
|
1ac71e5a3 pcmcia: convert p... |
158 |
link->config_flags |= CONF_ENABLE_IRQ; |
7feabb641 pcmcia: move conf... |
159 160 |
link->config_index = 1; link->config_regs = PRESENT_OPTION; |
6d00a3127 [ALSA] Fix and cl... |
161 |
|
2fa51107c ALSA: Return prop... |
162 163 |
*chip_ret = vxp; return 0; |
6d00a3127 [ALSA] Fix and cl... |
164 165 166 167 168 169 170 171 172 173 174 175 176 |
} /** * snd_vxpocket_assign_resources - initialize the hardware and card instance. * @port: i/o port for the card * @irq: irq number for the card * * this function assigns the specified port and irq, boot the card, * create pcm and control instances, and initialize the rest hardware. * * returns 0 if successful, or a negative error code. */ |
af26367f6 [ALSA] Remove xxx... |
177 |
static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq) |
6d00a3127 [ALSA] Fix and cl... |
178 179 |
{ int err; |
af26367f6 [ALSA] Remove xxx... |
180 |
struct snd_card *card = chip->card; |
6d00a3127 [ALSA] Fix and cl... |
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d ", port, irq); vxp->port = port; sprintf(card->shortname, "Digigram %s", card->driver); sprintf(card->longname, "%s at 0x%x, irq %i", card->shortname, port, irq); chip->irq = irq; if ((err = snd_vx_setup_firmware(chip)) < 0) return err; return 0; } /* * configuration callback */ |
15b99ac17 [PATCH] pcmcia: a... |
203 |
static int vxpocket_config(struct pcmcia_device *link) |
6d00a3127 [ALSA] Fix and cl... |
204 |
{ |
af26367f6 [ALSA] Remove xxx... |
205 |
struct vx_core *chip = link->priv; |
7c5af6ffd pcmcia: use dynam... |
206 |
int ret; |
6d00a3127 [ALSA] Fix and cl... |
207 208 209 |
snd_printdd(KERN_DEBUG "vxpocket_config called "); |
6d00a3127 [ALSA] Fix and cl... |
210 211 |
/* redefine hardware record according to the VERSION1 string */ |
af2b3b503 [PATCH] pcmcia: c... |
212 |
if (!strcmp(link->prod_id[1], "VX-POCKET")) { |
6d00a3127 [ALSA] Fix and cl... |
213 214 215 216 217 218 219 220 221 222 |
snd_printdd("VX-pocket is detected "); } else { snd_printdd("VX-pocket 440 is detected "); /* overwrite the hardware information */ chip->hw = &vxp440_hw; chip->type = vxp440_hw.type; strcpy(chip->card->driver, vxp440_hw.name); } |
90abdc3b9 pcmcia: do not us... |
223 |
ret = pcmcia_request_io(link); |
7c5af6ffd pcmcia: use dynam... |
224 225 |
if (ret) goto failed; |
08ef79490 ALSA: pcmcia - Us... |
226 |
ret = pcmcia_request_irq(link, snd_vx_irq_handler); |
7c5af6ffd pcmcia: use dynam... |
227 228 |
if (ret) goto failed; |
1ac71e5a3 pcmcia: convert p... |
229 |
ret = pcmcia_enable_device(link); |
7c5af6ffd pcmcia: use dynam... |
230 231 |
if (ret) goto failed; |
6d00a3127 [ALSA] Fix and cl... |
232 |
|
dd2e5a156 pcmcia: remove de... |
233 |
chip->dev = &link->dev; |
5ba094dbf [ALSA] vxpocket -... |
234 |
snd_card_set_dev(chip->card, chip->dev); |
6d00a3127 [ALSA] Fix and cl... |
235 |
|
9a017a910 pcmcia: do not us... |
236 237 |
if (snd_vxpocket_assign_resources(chip, link->resource[0]->start, link->irq) < 0) |
6d00a3127 [ALSA] Fix and cl... |
238 |
goto failed; |
79ca4f3f6 [ALSA] vxpocket -... |
239 |
return 0; |
6d00a3127 [ALSA] Fix and cl... |
240 |
|
6d00a3127 [ALSA] Fix and cl... |
241 |
failed: |
fba395eee [PATCH] pcmcia: r... |
242 |
pcmcia_disable_device(link); |
15b99ac17 [PATCH] pcmcia: a... |
243 |
return -ENODEV; |
6d00a3127 [ALSA] Fix and cl... |
244 |
} |
efe3cd105 [PATCH] pcmcia: f... |
245 |
#ifdef CONFIG_PM |
6d00a3127 [ALSA] Fix and cl... |
246 |
|
fba395eee [PATCH] pcmcia: r... |
247 |
static int vxp_suspend(struct pcmcia_device *link) |
6d00a3127 [ALSA] Fix and cl... |
248 |
{ |
af26367f6 [ALSA] Remove xxx... |
249 |
struct vx_core *chip = link->priv; |
6d00a3127 [ALSA] Fix and cl... |
250 |
|
efe3cd105 [PATCH] pcmcia: f... |
251 252 |
snd_printdd(KERN_DEBUG "SUSPEND "); |
efe3cd105 [PATCH] pcmcia: f... |
253 254 255 256 257 |
if (chip) { snd_printdd(KERN_DEBUG "snd_vx_suspend calling "); snd_vx_suspend(chip, PMSG_SUSPEND); } |
efe3cd105 [PATCH] pcmcia: f... |
258 259 260 |
return 0; } |
fba395eee [PATCH] pcmcia: r... |
261 |
static int vxp_resume(struct pcmcia_device *link) |
efe3cd105 [PATCH] pcmcia: f... |
262 |
{ |
efe3cd105 [PATCH] pcmcia: f... |
263 264 265 266 |
struct vx_core *chip = link->priv; snd_printdd(KERN_DEBUG "RESUME "); |
9940ec361 [PATCH] pcmcia: c... |
267 |
if (pcmcia_dev_present(link)) { |
efe3cd105 [PATCH] pcmcia: f... |
268 |
//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; |
0ed1cad17 [ALSA] vx-driver ... |
269 |
if (chip) { |
efe3cd105 [PATCH] pcmcia: f... |
270 271 272 |
snd_printdd(KERN_DEBUG "calling snd_vx_resume "); snd_vx_resume(chip); |
6d00a3127 [ALSA] Fix and cl... |
273 |
} |
6d00a3127 [ALSA] Fix and cl... |
274 |
} |
efe3cd105 [PATCH] pcmcia: f... |
275 276 |
snd_printdd(KERN_DEBUG "resume done! "); |
6d00a3127 [ALSA] Fix and cl... |
277 278 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
279 |
|
efe3cd105 [PATCH] pcmcia: f... |
280 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
281 282 283 |
/* */ |
15b99ac17 [PATCH] pcmcia: a... |
284 |
static int vxpocket_probe(struct pcmcia_device *p_dev) |
1da177e4c Linux-2.6.12-rc2 |
285 |
{ |
af26367f6 [ALSA] Remove xxx... |
286 |
struct snd_card *card; |
6d00a3127 [ALSA] Fix and cl... |
287 |
struct snd_vxpocket *vxp; |
bd7dd77c2 ALSA: Convert to ... |
288 |
int i, err; |
6d00a3127 [ALSA] Fix and cl... |
289 290 291 |
/* find an empty slot from the card list */ for (i = 0; i < SNDRV_CARDS; i++) { |
27fe0f4b9 [ALSA] sound/pcmc... |
292 |
if (!(card_alloc & (1 << i))) |
6d00a3127 [ALSA] Fix and cl... |
293 294 295 296 297 |
break; } if (i >= SNDRV_CARDS) { snd_printk(KERN_ERR "vxpocket: too many cards found "); |
efe3cd105 [PATCH] pcmcia: f... |
298 |
return -EINVAL; |
6d00a3127 [ALSA] Fix and cl... |
299 300 |
} if (! enable[i]) |
efe3cd105 [PATCH] pcmcia: f... |
301 |
return -ENODEV; /* disabled explicitly */ |
6d00a3127 [ALSA] Fix and cl... |
302 303 |
/* ok, create a card instance */ |
bd7dd77c2 ALSA: Convert to ... |
304 305 |
err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card); if (err < 0) { |
6d00a3127 [ALSA] Fix and cl... |
306 307 |
snd_printk(KERN_ERR "vxpocket: cannot create a card instance "); |
bd7dd77c2 ALSA: Convert to ... |
308 |
return err; |
6d00a3127 [ALSA] Fix and cl... |
309 |
} |
2fa51107c ALSA: Return prop... |
310 311 |
err = snd_vxpocket_new(card, ibl[i], p_dev, &vxp); if (err < 0) { |
6d00a3127 [ALSA] Fix and cl... |
312 |
snd_card_free(card); |
2fa51107c ALSA: Return prop... |
313 |
return err; |
6d00a3127 [ALSA] Fix and cl... |
314 |
} |
0ed1cad17 [ALSA] vx-driver ... |
315 |
card->private_data = vxp; |
6d00a3127 [ALSA] Fix and cl... |
316 |
|
adf111e6f [ALSA] vxpocket -... |
317 |
vxp->index = i; |
6d00a3127 [ALSA] Fix and cl... |
318 |
card_alloc |= 1 << i; |
fd238232c [PATCH] pcmcia: e... |
319 |
vxp->p_dev = p_dev; |
efe3cd105 [PATCH] pcmcia: f... |
320 |
|
15b99ac17 [PATCH] pcmcia: a... |
321 |
return vxpocket_config(p_dev); |
1da177e4c Linux-2.6.12-rc2 |
322 |
} |
fba395eee [PATCH] pcmcia: r... |
323 |
static void vxpocket_detach(struct pcmcia_device *link) |
1da177e4c Linux-2.6.12-rc2 |
324 |
{ |
6d00a3127 [ALSA] Fix and cl... |
325 |
struct snd_vxpocket *vxp; |
af26367f6 [ALSA] Remove xxx... |
326 |
struct vx_core *chip; |
6d00a3127 [ALSA] Fix and cl... |
327 328 329 330 331 |
if (! link) return; vxp = link->priv; |
af26367f6 [ALSA] Remove xxx... |
332 |
chip = (struct vx_core *)vxp; |
6d00a3127 [ALSA] Fix and cl... |
333 |
card_alloc &= ~(1 << vxp->index); |
6d00a3127 [ALSA] Fix and cl... |
334 335 336 |
chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ snd_card_disconnect(chip->card); vxpocket_release(link); |
2b29b13c5 [ALSA] Deprecate ... |
337 |
snd_card_free_when_closed(chip->card); |
1da177e4c Linux-2.6.12-rc2 |
338 339 340 341 342 |
} /* * Module entry points */ |
4ef7e7144 pcmcia: Make stru... |
343 |
static const struct pcmcia_device_id vxp_ids[] = { |
e9a07afd9 [PATCH] pcmcia: i... |
344 345 346 347 |
PCMCIA_DEVICE_MANF_CARD(0x01f1, 0x0100), PCMCIA_DEVICE_NULL }; MODULE_DEVICE_TABLE(pcmcia, vxp_ids); |
1da177e4c Linux-2.6.12-rc2 |
348 349 |
static struct pcmcia_driver vxp_cs_driver = { .owner = THIS_MODULE, |
2e9b981a7 pcmcia: move driv... |
350 |
.name = "snd-vxpocket", |
15b99ac17 [PATCH] pcmcia: a... |
351 |
.probe = vxpocket_probe, |
efe3cd105 [PATCH] pcmcia: f... |
352 |
.remove = vxpocket_detach, |
e9a07afd9 [PATCH] pcmcia: i... |
353 |
.id_table = vxp_ids, |
efe3cd105 [PATCH] pcmcia: f... |
354 355 356 357 |
#ifdef CONFIG_PM .suspend = vxp_suspend, .resume = vxp_resume, #endif |
1da177e4c Linux-2.6.12-rc2 |
358 359 360 361 362 363 364 365 366 367 |
}; static int __init init_vxpocket(void) { return pcmcia_register_driver(&vxp_cs_driver); } static void __exit exit_vxpocket(void) { pcmcia_unregister_driver(&vxp_cs_driver); |
1da177e4c Linux-2.6.12-rc2 |
368 369 370 371 |
} module_init(init_vxpocket); module_exit(exit_vxpocket); |