Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 351225 | Differences between
and this patch

Collapse All | Expand All

(-)sound/pci/hda/hda_codec.c.orig (-2 / +44 lines)
Lines 238-243 Link Here
238
}
238
}
239
239
240
/**
240
/**
241
 * snd_hda_codec_wallclock - get the wallclock counter
242
 * @codec: the HDA codec
243
 *
244
 * Get the wallclock counter
245
 *
246
 * Returns the obtained value, or -1 for an error.
247
 */
248
unsigned int snd_hda_codec_wallclock(struct hda_codec *codec)
249
{
250
	u32 res;
251
	if(codec->bus->ops.get_wallclock)
252
		res = codec->bus->ops.get_wallclock(codec);
253
	else
254
		res = (u32)-1;
255
	return res;
256
}
257
EXPORT_SYMBOL_HDA(snd_hda_codec_wallclock);
258
259
/**
241
 * snd_hda_codec_read - send a command and get the response
260
 * snd_hda_codec_read - send a command and get the response
242
 * @codec: the HDA codec
261
 * @codec: the HDA codec
243
 * @nid: NID to send the command
262
 * @nid: NID to send the command
Lines 674-679 Link Here
674
	return 0;
693
	return 0;
675
}
694
}
676
695
696
void snd_hda_codec_remove_notify_all(struct hda_bus *bus)
697
{
698
	struct list_head *p, *n;
699
700
	if (! bus)
701
		return;
702
	list_for_each_safe(p, n, &bus->codec_list) {
703
		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
704
705
		if (codec && codec->patch_ops.exit) {
706
			codec->patch_ops.exit(codec);
707
		}
708
	}
709
}
710
EXPORT_SYMBOL_HDA(snd_hda_codec_remove_notify_all);
711
677
/*
712
/*
678
 * destructor
713
 * destructor
679
 */
714
 */
Lines 1366-1372 Link Here
1366
	}
1401
	}
1367
	if (codec->preset && codec->preset->patch) {
1402
	if (codec->preset && codec->preset->patch) {
1368
		err = codec->preset->patch(codec);
1403
		err = codec->preset->patch(codec);
1369
		goto patched;
1404
		if (err != -ENOSYS)
1405
			goto patched;
1370
	}
1406
	}
1371
1407
1372
	/* call the default parser */
1408
	/* call the default parser */
Lines 2300-2312 Link Here
2300
{
2336
{
2301
	struct hda_bus *bus = codec->bus;
2337
	struct hda_bus *bus = codec->bus;
2302
	struct snd_card *card = bus->card;
2338
	struct snd_card *card = bus->card;
2303
	int i;
2339
	int i, err;
2304
2340
2305
	if (snd_hda_lock_devices(bus) < 0)
2341
	if (snd_hda_lock_devices(bus) < 0)
2306
		return -EBUSY;
2342
		return -EBUSY;
2307
2343
2308
	/* OK, let it free */
2344
	/* OK, let it free */
2309
2345
2346
	if (codec->patch_ops.exit) {
2347
		err = codec->patch_ops.exit(codec);
2348
		if (err < 0)
2349
			return err;
2350
	}
2351
2310
#ifdef CONFIG_SND_HDA_POWER_SAVE
2352
#ifdef CONFIG_SND_HDA_POWER_SAVE
2311
	cancel_delayed_work_sync(&codec->power_work);
2353
	cancel_delayed_work_sync(&codec->power_work);
2312
	codec->power_on = 0;
2354
	codec->power_on = 0;
(-)sound/pci/hda/hda_codec.h.orig (+7 lines)
Lines 600-605 Link Here
600
	int (*command)(struct hda_bus *bus, unsigned int cmd);
600
	int (*command)(struct hda_bus *bus, unsigned int cmd);
601
	/* get a response from the last command */
601
	/* get a response from the last command */
602
	unsigned int (*get_response)(struct hda_bus *bus, unsigned int addr);
602
	unsigned int (*get_response)(struct hda_bus *bus, unsigned int addr);
603
	/* get the wall clock counter */
604
	u32 (*get_wallclock)(struct hda_codec *codec);
605
	/* get the link position counter */
606
	u32 (*get_linkpos)(struct snd_pcm_substream *substream);
603
	/* free the private data */
607
	/* free the private data */
604
	void (*private_free)(struct hda_bus *);
608
	void (*private_free)(struct hda_bus *);
605
	/* attach a PCM stream */
609
	/* attach a PCM stream */
Lines 698-703 Link Here
698
	int (*build_controls)(struct hda_codec *codec);
702
	int (*build_controls)(struct hda_codec *codec);
699
	int (*build_pcms)(struct hda_codec *codec);
703
	int (*build_pcms)(struct hda_codec *codec);
700
	int (*init)(struct hda_codec *codec);
704
	int (*init)(struct hda_codec *codec);
705
	int (*exit)(struct hda_codec *codec);
701
	void (*free)(struct hda_codec *codec);
706
	void (*free)(struct hda_codec *codec);
702
	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
707
	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
703
	void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
708
	void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
Lines 895-905 Link Here
895
		    struct hda_bus **busp);
900
		    struct hda_bus **busp);
896
int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
901
int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
897
		      struct hda_codec **codecp);
902
		      struct hda_codec **codecp);
903
void snd_hda_codec_remove_notify_all(struct hda_bus *bus);
898
int snd_hda_codec_configure(struct hda_codec *codec);
904
int snd_hda_codec_configure(struct hda_codec *codec);
899
905
900
/*
906
/*
901
 * low level functions
907
 * low level functions
902
 */
908
 */
909
unsigned int snd_hda_codec_wallclock(struct hda_codec *codec);
903
unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
910
unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
904
				int direct,
911
				int direct,
905
				unsigned int verb, unsigned int parm);
912
				unsigned int verb, unsigned int parm);
(-)sound/pci/hda/hda_intel.c.orig (+20 lines)
Lines 56-61 Link Here
56
#include <linux/vgaarb.h>
56
#include <linux/vgaarb.h>
57
#include <linux/vga_switcheroo.h>
57
#include <linux/vga_switcheroo.h>
58
#include "hda_codec.h"
58
#include "hda_codec.h"
59
#include "hda_local.h"
59
60
60
61
61
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
62
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
Lines 660-665 Link Here
660
 * Interface for HD codec
661
 * Interface for HD codec
661
 */
662
 */
662
663
664
static u32 azx_get_wallclock(struct hda_codec *codec)
665
{
666
	struct azx *chip = codec->bus->private_data;
667
668
	return azx_readl(chip, WALLCLK);
669
}
670
671
static u32 azx_get_linkpos(struct snd_pcm_substream *substream)
672
{
673
	struct azx_dev *azx_dev = get_azx_dev(substream);
674
675
	return azx_sd_readl(azx_dev, SD_LPIB);
676
}
677
663
/*
678
/*
664
 * CORB / RIRB interface
679
 * CORB / RIRB interface
665
 */
680
 */
Lines 1575-1580 Link Here
1575
	bus_temp.pci = chip->pci;
1590
	bus_temp.pci = chip->pci;
1576
	bus_temp.ops.command = azx_send_cmd;
1591
	bus_temp.ops.command = azx_send_cmd;
1577
	bus_temp.ops.get_response = azx_get_response;
1592
	bus_temp.ops.get_response = azx_get_response;
1593
	bus_temp.ops.get_wallclock = azx_get_wallclock;
1594
	bus_temp.ops.get_linkpos = azx_get_linkpos;
1578
	bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
1595
	bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
1579
	bus_temp.ops.bus_reset = azx_bus_reset;
1596
	bus_temp.ops.bus_reset = azx_bus_reset;
1580
#ifdef CONFIG_SND_HDA_POWER_SAVE
1597
#ifdef CONFIG_SND_HDA_POWER_SAVE
Lines 3233-3238 Link Here
3233
static void __devexit azx_remove(struct pci_dev *pci)
3250
static void __devexit azx_remove(struct pci_dev *pci)
3234
{
3251
{
3235
	struct snd_card *card = pci_get_drvdata(pci);
3252
	struct snd_card *card = pci_get_drvdata(pci);
3253
	struct azx *chip = card->private_data;
3254
3255
	snd_hda_codec_remove_notify_all(chip->bus);
3236
	if (card)
3256
	if (card)
3237
		snd_card_free(card);
3257
		snd_card_free(card);
3238
	pci_set_drvdata(pci, NULL);
3258
	pci_set_drvdata(pci, NULL);
(-)sound/pci/hda/patch_conexant.c.orig (-35 / +760 lines)
Lines 1-10 Link Here
1
/*
1
/*
2
 * HD audio interface patch for Conexant HDA audio codec
2
 * HD audio interface patch for Conexant HDA audio/modem codec
3
 *
3
 *
4
 * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
4
 * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
5
 * 		      Takashi Iwai <tiwai@suse.de>
5
 * 		      Takashi Iwai <tiwai@suse.de>
6
 * 		      Tobin Davis  <tdavis@dsl-only.net>
6
 * 		      Tobin Davis  <tdavis@dsl-only.net>
7
 *
7
 *
8
 * Copyright (c) 2005-2010 Linuxant inc.
9
 *
8
 *  This driver is free software; you can redistribute it and/or modify
10
 *  This driver is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
11
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  the Free Software Foundation; either version 2 of the License, or
Lines 53-58 Link Here
53
#define AUTO_MIC_PORTB		(1 << 1)
55
#define AUTO_MIC_PORTB		(1 << 1)
54
#define AUTO_MIC_PORTC		(1 << 2)
56
#define AUTO_MIC_PORTC		(1 << 2)
55
57
58
#if defined(__i386__)
59
#define __shimcall__ __attribute__((regparm(0)))
60
#else
61
#define __shimcall__
62
#endif
63
64
//#define CONFIG_SND_DEBUG
65
56
struct pin_dac_pair {
66
struct pin_dac_pair {
57
	hda_nid_t pin;
67
	hda_nid_t pin;
58
	hda_nid_t dac;
68
	hda_nid_t dac;
Lines 118-124 Link Here
118
	int num_channel_mode;
128
	int num_channel_mode;
119
129
120
	/* PCM information */
130
	/* PCM information */
121
	struct hda_pcm pcm_rec[2];	/* used in build_pcms() */
131
	struct hda_pcm pcm_rec[3];	/* used in build_pcms() */
122
132
123
	unsigned int spdif_route;
133
	unsigned int spdif_route;
124
134
Lines 164-169 Link Here
164
174
165
	unsigned int beep_amp;
175
	unsigned int beep_amp;
166
176
177
	/* HSF modem */
178
	void *modem_devnode;
179
	unsigned int modem_stream_tags[2];
180
	int modem_do_prepare[2];
181
	void (*modem_cbHdaEvent)(void *Context, unsigned int res) __shimcall__;
182
	void *modem_cbHdaEventContext;
183
	unsigned char modem_cbHdaTag;
184
167
	/* extra EAPD pins */
185
	/* extra EAPD pins */
168
	unsigned int num_eapds;
186
	unsigned int num_eapds;
169
	hda_nid_t eapds[4];
187
	hda_nid_t eapds[4];
Lines 257-263 Link Here
257
	return 0;
275
	return 0;
258
}
276
}
259
277
278
#if defined(__i386__)
279
#define __shimcall__ __attribute__((regparm(0)))
280
#else
281
#define __shimcall__
282
#endif
283
284
//#define CONFIG_SND_DEBUG
285
static int conexant_modem_pcm_prepare(struct hda_pcm_stream *hinfo,
286
                             struct hda_codec *codec,
287
                             unsigned int stream_tag,
288
                             unsigned int format,
289
                             struct snd_pcm_substream *substream)
290
{
291
       struct conexant_spec *spec = codec->spec;
292
293
       //printk(KERN_DEBUG"%s: codec=%p stream=%d stream_tag=%x format=0x%x substream=%p\n", __FUNCTION__, codec, substream->stream, stream_tag, format, substream);
294
295
       spec->modem_stream_tags[substream->stream] = stream_tag;
296
297
       return 0;
298
}
299
300
static int conexant_modem_pcm_open(struct hda_pcm_stream *hinfo, struct hda_codec *codec,
301
                           struct snd_pcm_substream *substream)
302
{
303
       static unsigned int rates[] = { 16000 };
304
       static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
305
               .count = ARRAY_SIZE(rates),
306
               .list = rates,
307
               .mask = 0,
308
       };
309
310
       //printk(KERN_DEBUG"%s: codec=%p substream=%p\n", __FUNCTION__, codec, substream);
260
311
312
       return snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
313
}
261
314
262
static const struct hda_pcm_stream conexant_pcm_analog_playback = {
315
static const struct hda_pcm_stream conexant_pcm_analog_playback = {
263
	.substreams = 1,
316
	.substreams = 1,
Lines 337-374 Link Here
337
	},
390
	},
338
};
391
};
339
392
393
static struct hda_pcm_stream conexant_modem_pcm = {
394
       .substreams = 1,
395
       .channels_min = 1,
396
       .channels_max = 1,
397
       .nid = 0x1,
398
       .rates = SNDRV_PCM_RATE_16000,
399
       .formats = SNDRV_PCM_FMTBIT_S16_LE,
400
       .maxbps = 16,
401
       .ops = {
402
               .open = conexant_modem_pcm_open,
403
               .prepare = conexant_modem_pcm_prepare,
404
       },
405
};
406
340
static int conexant_build_pcms(struct hda_codec *codec)
407
static int conexant_build_pcms(struct hda_codec *codec)
341
{
408
{
342
	struct conexant_spec *spec = codec->spec;
409
	struct conexant_spec *spec = codec->spec;
343
	struct hda_pcm *info = spec->pcm_rec;
410
	struct hda_pcm *info = spec->pcm_rec;
344
411
345
	codec->num_pcms = 1;
412
	codec->num_pcms = 0;
346
	codec->pcm_info = info;
413
	codec->pcm_info = info;
347
414
348
	info->name = "CONEXANT Analog";
415
	if (codec->afg) {
349
	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
416
                info->name = "CONEXANT Analog";
350
	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
417
                info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
351
		spec->multiout.max_channels;
418
                info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
352
	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
419
                        spec->multiout.max_channels;
353
		spec->multiout.dac_nids[0];
420
                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
354
	if (spec->capture_stream)
421
                        spec->multiout.dac_nids[0];
355
		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
422
                if (codec->vendor_id == 0x14f15051)
356
	else {
423
                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
357
		if (codec->vendor_id == 0x14f15051)
424
                                cx5051_pcm_analog_capture;
358
			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
425
                else
359
				cx5051_pcm_analog_capture;
426
                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
360
		else {
427
                                conexant_pcm_analog_capture;
361
			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
428
                info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
362
				conexant_pcm_analog_capture;
429
                info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
363
			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
364
				spec->num_adc_nids;
365
		}
366
	}
367
	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
368
369
	if (spec->multiout.dig_out_nid) {
370
		info++;
430
		info++;
371
		codec->num_pcms++;
431
		codec->num_pcms++;
432
	}
433
434
        if (spec->multiout.dig_out_nid) {
372
		info->name = "Conexant Digital";
435
		info->name = "Conexant Digital";
373
		info->pcm_type = HDA_PCM_TYPE_SPDIF;
436
		info->pcm_type = HDA_PCM_TYPE_SPDIF;
374
		info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
437
		info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
Lines 383-388 Link Here
383
		}
446
		}
384
		if (spec->slave_dig_outs[0])
447
		if (spec->slave_dig_outs[0])
385
			codec->slave_dig_outs = spec->slave_dig_outs;
448
			codec->slave_dig_outs = spec->slave_dig_outs;
449
450
		info++;
451
		codec->num_pcms++;
452
	}
453
454
	if (codec->mfg) {
455
		conexant_modem_pcm.nid = codec->mfg;
456
457
		info->name = "Conexant HSF Modem";
458
		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_modem_pcm;
459
		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = conexant_modem_pcm.nid;
460
		info->stream[SNDRV_PCM_STREAM_CAPTURE]  = conexant_modem_pcm;
461
		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid  = conexant_modem_pcm.nid;
462
		info->pcm_type = HDA_PCM_TYPE_MODEM;
463
464
		info++;
465
		codec->num_pcms++;
386
	}
466
	}
387
467
388
	return 0;
468
	return 0;
Lines 433-448 Link Here
433
	snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
513
	snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
434
}
514
}
435
515
516
static void *conexant_hsfmodem_interface_funcs[];
517
436
static int conexant_init(struct hda_codec *codec)
518
static int conexant_init(struct hda_codec *codec)
437
{
519
{
438
	struct conexant_spec *spec = codec->spec;
520
	struct conexant_spec *spec = codec->spec;
439
	int i;
521
        int i, ret;
522
523
        //printk(KERN_DEBUG"%s: codec=%p\n", __FUNCTION__, codec);
524
        if(codec->mfg) {
525
                int (*cnxthwhda_probe)(void *codec, struct device *hwDev, void **ppDevNode, void **ppInterfaceFuncs);
526
 
527
                //snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0);
528
 
529
                cnxthwhda_probe = (void*)symbol_request(cnxthwhda_probe);
530
                if(!cnxthwhda_probe) {
531
                        printk(KERN_ERR"%s: Conexant HSF modem detected but driver not present\n", __FUNCTION__);
532
                        if(!codec->afg)
533
                                return -ENOENT;
534
                } else {
535
                        ret = cnxthwhda_probe(codec, codec->bus->card->dev, &spec->modem_devnode, conexant_hsfmodem_interface_funcs);
536
                        if(ret) {
537
                                printk(KERN_ERR"%s: cnxthwhda_probe() failed: %d\n", __FUNCTION__, ret);
538
                                symbol_put(cnxthwhda_probe);
539
                                if(!codec->afg)
540
                                        return ret;
541
                        }
542
                }
543
        }
440
544
441
	for (i = 0; i < spec->num_init_verbs; i++)
545
	for (i = 0; i < spec->num_init_verbs; i++)
442
		snd_hda_sequence_write(codec, spec->init_verbs[i]);
546
		snd_hda_sequence_write(codec, spec->init_verbs[i]);
443
	return 0;
547
	return 0;
444
}
548
}
445
549
550
static int conexant_exit(struct hda_codec *codec)
551
{
552
        struct conexant_spec *spec = codec->spec;
553
 
554
        //printk(KERN_DEBUG"%s: codec=%p spec=%p\n", __FUNCTION__, codec, spec);
555
 
556
        if(codec->mfg && spec && spec->modem_devnode) {
557
                void (*cnxthwhda_remove)(void *ptr);
558
 
559
                cnxthwhda_remove = (void*)symbol_request(cnxthwhda_remove);
560
                if(cnxthwhda_remove) {
561
                        cnxthwhda_remove(spec->modem_devnode);
562
                        spec->modem_devnode = NULL;
563
                        symbol_put(cnxthwhda_remove);
564
                        symbol_put(cnxthwhda_probe);
565
                } else {
566
                        printk(KERN_ERR"%s: symbol_request(cnxthwhda_remove) failed\n", __FUNCTION__);
567
                }
568
        }
569
 
570
        return 0;
571
}
572
446
static void conexant_free(struct hda_codec *codec)
573
static void conexant_free(struct hda_codec *codec)
447
{
574
{
448
	struct conexant_spec *spec = codec->spec;
575
	struct conexant_spec *spec = codec->spec;
Lines 451-456 Link Here
451
	kfree(spec);
578
	kfree(spec);
452
}
579
}
453
580
581
static void conexant_unsol_event(struct hda_codec *codec, unsigned int res)
582
{
583
        struct conexant_spec *spec = codec->spec;
584
 
585
        //printk(KERN_DEBUG"%s: codec=%p res=0x%02x spec=%p cbHdaEvent=%p\n", __FUNCTION__, codec, res, spec, spec->modem_cbHdaEvent);
586
 
587
        if(codec->mfg && spec && spec->modem_cbHdaEvent) {
588
                if(((res >> 26) & 0x3f) == spec->modem_cbHdaTag) {
589
                        //printk(KERN_DEBUG"%s: res=0x%02x cbHdaEvent=%p\n", __FUNCTION__, res, spec->modem_bHdaEvent);
590
                        //printk(KERN_DEBUG"%s: calling cbHdaEvent=%p ctx=%p\n", __FUNCTION__, spec->modem_cHdaEvent, spec->modem_cbHdaEventContext);
591
                        spec->modem_cbHdaEvent(spec->modem_cbHdaEventContext, res);
592
                } else {
593
                        printk(KERN_DEBUG"%s: ignoring res=0x08%x\n", __FUNCTION__, res);
594
                }
595
        }
596
}
597
598
typedef struct tagHDAOSHAL {
599
        void *hda_codec;
600
        int bInSuspendResume;
601
} HDAOSHAL, *PHDAOSHAL;
602
 
603
typedef struct tagOS_DEVNODE {
604
        void *hwDev;
605
        // intentionally left incomplete
606
} OS_DEVNODE, *POS_DEVNODE;
607
 
608
#ifdef CONFIG_PM
609
static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
610
{
611
        struct conexant_spec *spec = codec->spec;
612
        int (*cnxthwhda_suspend)(void *devnode, pm_message_t state);
613
        int ret = 0;
614
 
615
        //printk(KERN_DEBUG"%s: codec=%p spec=%p state=0x%x\n", __FUNCTION__, codec, spec, *((u32 *)&state));
616
 
617
        if(spec && spec->modem_devnode) {
618
                cnxthwhda_suspend = (void*)symbol_request(cnxthwhda_suspend);
619
                if(!cnxthwhda_suspend) {
620
                        printk(KERN_ERR"%s: symbol_request(cnxthwhda_suspend) failed\n", __FUNCTION__);
621
                        return -ENOSYS;
622
                }
623
 
624
                if(((POS_DEVNODE)spec->modem_devnode)->hwDev) {
625
                        ((PHDAOSHAL)((POS_DEVNODE)spec->modem_devnode)->hwDev)->bInSuspendResume++;
626
                }
627
                ret = cnxthwhda_suspend(spec->modem_devnode, state);
628
                if(((POS_DEVNODE)spec->modem_devnode)->hwDev) {
629
                        ((PHDAOSHAL)((POS_DEVNODE)spec->modem_devnode)->hwDev)->bInSuspendResume--;
630
                }
631
                symbol_put(cnxthwhda_suspend);
632
        }
633
 
634
        return ret;
635
}
636
637
static int conexant_resume(struct hda_codec *codec)
638
{
639
        struct conexant_spec *spec = codec->spec;
640
        int ret = 0;
641
        hda_nid_t mfg;
642
643
        mfg = codec->mfg;
644
        codec->mfg = 0;
645
        codec->patch_ops.init(codec);
646
        codec->mfg = mfg;
647
648
        snd_hda_codec_resume_amp(codec);
649
        snd_hda_codec_resume_cache(codec);
650
651
        if(spec && spec->modem_devnode) {
652
                int (*cnxthwhda_resume)(void *devnode);
653
654
                //printk(KERN_DEBUG"%s: codec=%p spec=%p\n", __FUNCTION__, codec, spec);
655
656
                cnxthwhda_resume = (void*)symbol_request(cnxthwhda_resume);
657
                if(!cnxthwhda_resume) {
658
                        printk(KERN_ERR"%s: symbol_request(cnxthwhda_resume) failed\n", __FUNCTION__);
659
                        return -ENOSYS;
660
                }
661
662
        //snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0);
663
664
                if(((POS_DEVNODE)spec->modem_devnode)->hwDev) {
665
                        ((PHDAOSHAL)((POS_DEVNODE)spec->modem_devnode)->hwDev)->bInSuspendResume++;
666
                }
667
668
                ret = cnxthwhda_resume(spec->modem_devnode);
669
670
                if(((POS_DEVNODE)spec->modem_devnode)->hwDev) {
671
                        ((PHDAOSHAL)((POS_DEVNODE)spec->modem_devnode)->hwDev)->bInSuspendResume--;
672
                }
673
674
                symbol_put(cnxthwhda_resume);
675
        }
676
677
        return ret;
678
}
679
#endif
680
454
static const struct snd_kcontrol_new cxt_capture_mixers[] = {
681
static const struct snd_kcontrol_new cxt_capture_mixers[] = {
455
	{
682
	{
456
		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
683
		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
Lines 565-571 Link Here
565
	.build_controls = conexant_build_controls,
792
	.build_controls = conexant_build_controls,
566
	.build_pcms = conexant_build_pcms,
793
	.build_pcms = conexant_build_pcms,
567
	.init = conexant_init,
794
	.init = conexant_init,
795
	.exit = conexant_exit,
568
	.free = conexant_free,
796
	.free = conexant_free,
797
        .unsol_event = conexant_unsol_event,
798
#ifdef CONFIG_PM
799
        .suspend = conexant_suspend,
800
        .resume = conexant_resume,
801
#endif
569
	.set_power_state = conexant_set_power,
802
	.set_power_state = conexant_set_power,
570
#ifdef CONFIG_SND_HDA_POWER_SAVE
803
#ifdef CONFIG_SND_HDA_POWER_SAVE
571
	.suspend = conexant_suspend,
804
	.suspend = conexant_suspend,
Lines 581-586 Link Here
581
#endif
814
#endif
582
815
583
static int patch_conexant_auto(struct hda_codec *codec);
816
static int patch_conexant_auto(struct hda_codec *codec);
817
818
static int patch_cxthsfmodem(struct hda_codec *codec)
819
{
820
        struct conexant_spec *spec;
821
        int (*cnxthwhda_probe)(void *codec, struct device *hwDev, void **ppDevNode);
822
823
        //printk(KERN_DEBUG"%s: codec=%p\n", __FUNCTION__, codec);
824
        if(!codec->mfg) { // we only support modems here
825
                return -ENODEV;
826
        }
827
828
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
829
        if (!spec)
830
                return -ENOMEM;
831
        codec->spec = spec;
832
833
        codec->patch_ops = conexant_patch_ops;
834
835
        cnxthwhda_probe = (void*)symbol_request(cnxthwhda_probe);
836
        if(cnxthwhda_probe) {
837
                symbol_put(cnxthwhda_probe);
838
        } else {
839
                printk(KERN_ERR"%s: Conexant HSF modem detected but driver not present\n", __FUNCTION__);
840
                codec->spec = NULL;
841
                memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
842
                kfree(spec);
843
                return -ENOSYS;
844
        }
845
846
        return 0;
847
}
848
584
/*
849
/*
585
 * EAPD control
850
 * EAPD control
586
 * the private value = nid | (invert << 8)
851
 * the private value = nid | (invert << 8)
Lines 752-764 Link Here
752
static void cxt5045_hp_automic(struct hda_codec *codec)
1017
static void cxt5045_hp_automic(struct hda_codec *codec)
753
{
1018
{
754
	static const struct hda_verb mic_jack_on[] = {
1019
	static const struct hda_verb mic_jack_on[] = {
755
		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1020
                {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | AC_AMP_MUTE},
756
		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1021
                {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT},
1022
                {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
757
		{}
1023
		{}
758
	};
1024
	};
759
	static const struct hda_verb mic_jack_off[] = {
1025
	static const struct hda_verb mic_jack_off[] = {
760
		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1026
                {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | AC_AMP_MUTE},
761
		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1027
                {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT},
1028
                {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
762
		{}
1029
		{}
763
	};
1030
	};
764
	unsigned int present;
1031
	unsigned int present;
Lines 788-802 Link Here
788
static void cxt5045_hp_unsol_event(struct hda_codec *codec,
1055
static void cxt5045_hp_unsol_event(struct hda_codec *codec,
789
				   unsigned int res)
1056
				   unsigned int res)
790
{
1057
{
791
	res >>= 26;
1058
	switch (res >> 26) {
792
	switch (res) {
793
	case CONEXANT_HP_EVENT:
1059
	case CONEXANT_HP_EVENT:
1060
		//printk("%s: CONEXANT_HP_EVENT\n", __FUNCTION__);
794
		cxt5045_hp_automute(codec);
1061
		cxt5045_hp_automute(codec);
795
		break;
1062
		break;
796
	case CONEXANT_MIC_EVENT:
1063
	case CONEXANT_MIC_EVENT:
1064
		//printk("%s: CONEXANT_MIC_EVENT\n", __FUNCTION__);
797
		cxt5045_hp_automic(codec);
1065
		cxt5045_hp_automic(codec);
798
		break;
1066
		break;
799
1067
        default:
1068
                //printk("%s: CONEXANT_OTHER_EVENT\n", __FUNCTION__);
1069
                conexant_unsol_event(codec, res);
1070
                break;
800
	}
1071
	}
801
}
1072
}
802
1073
Lines 1184-1189 Link Here
1184
	if (spec->beep_amp)
1455
	if (spec->beep_amp)
1185
		snd_hda_attach_beep_device(codec, spec->beep_amp);
1456
		snd_hda_attach_beep_device(codec, spec->beep_amp);
1186
1457
1458
        if(codec->mfg) {
1459
                int (*cnxthwhda_probe)(void *codec, struct device *hwDev, void **ppDevNode);
1460
                cnxthwhda_probe = (void*)symbol_request(cnxthwhda_probe);
1461
                if(cnxthwhda_probe)
1462
                        symbol_put(cnxthwhda_probe);
1463
                else
1464
                        printk(KERN_ERR"%s: Conexant HSF modem detected but driver not present\n", __FUNCTION__);
1465
        }
1466
1187
	return 0;
1467
	return 0;
1188
}
1468
}
1189
1469
Lines 1222-1228 Link Here
1222
	 * the headphone jack
1502
	 * the headphone jack
1223
	 */
1503
	 */
1224
	bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1504
	bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1225
	/* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1505
	/* NOTE: Conexant codec needs the index for *OUTPUT* amp of
1226
	 * pin widgets unlike other codecs.  In this case, we need to
1506
	 * pin widgets unlike other codecs.  In this case, we need to
1227
	 * set index 0x01 for the volume from the mixer amp 0x19.
1507
	 * set index 0x01 for the volume from the mixer amp 0x19.
1228
	 */
1508
	 */
Lines 1573-1578 Link Here
1573
		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1853
		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1574
#endif	
1854
#endif	
1575
	}
1855
	}
1856
1857
        if(codec->mfg) {
1858
                int (*cnxthwhda_probe)(void *codec, struct device *hwDev, void **ppDevNode);
1859
                cnxthwhda_probe = (void*)symbol_request(cnxthwhda_probe);
1860
                if(cnxthwhda_probe)
1861
                        symbol_put(cnxthwhda_probe);
1862
                else
1863
                        printk(KERN_ERR"%s: Conexant HSF modem detected but driver not present\n", __FUNCTION__);
1864
        }
1865
1576
	spec->vmaster_nid = 0x13;
1866
	spec->vmaster_nid = 0x13;
1577
1867
1578
	switch (codec->subsystem_id >> 16) {
1868
	switch (codec->subsystem_id >> 16) {
Lines 1689-1694 Link Here
1689
	case CXT5051_PORTC_EVENT:
1979
	case CXT5051_PORTC_EVENT:
1690
		cxt5051_portc_automic(codec);
1980
		cxt5051_portc_automic(codec);
1691
		break;
1981
		break;
1982
        default:
1983
                conexant_unsol_event(codec, res);
1984
                break;
1692
	}
1985
	}
1693
}
1986
}
1694
1987
Lines 1963-1968 Link Here
1963
	if (spec->beep_amp)
2256
	if (spec->beep_amp)
1964
		snd_hda_attach_beep_device(codec, spec->beep_amp);
2257
		snd_hda_attach_beep_device(codec, spec->beep_amp);
1965
2258
2259
        if(codec->mfg) {
2260
                int (*cnxthwhda_probe)(void *codec, struct device *hwDev, void **ppDevNode);
2261
                cnxthwhda_probe = (void*)symbol_request(cnxthwhda_probe);
2262
                if(cnxthwhda_probe)
2263
                        symbol_put(cnxthwhda_probe);
2264
                else
2265
                        printk(KERN_ERR"%s: Conexant HSF modem detected but driver not present\n", __FUNCTION__);
2266
        }
2267
	
1966
	return 0;
2268
	return 0;
1967
}
2269
}
1968
2270
Lines 4562-4567 Link Here
4562
/*
4864
/*
4563
 */
4865
 */
4564
4866
4867
typedef enum {
4868
        OsHdaStreamStateReset = 0,
4869
        OsHdaStreamStateStop  = 1,
4870
        OsHdaStreamStateRun   = 2
4871
} OSHDA_STREAM_STATE;
4872
4873
static __shimcall__
4874
unsigned int conexant_hsfmodem_OsHdaCodecGetAddr(PHDAOSHAL pHdaOsHal)
4875
{
4876
        return ((struct hda_codec *)pHdaOsHal->hda_codec)->addr;
4877
}
4878
4879
static __shimcall__
4880
unsigned int conexant_hsfmodem_OsHdaCodecGetVendorId(PHDAOSHAL pHdaOsHal)
4881
{
4882
        return ((struct hda_codec *)pHdaOsHal->hda_codec)->vendor_id;
4883
}
4884
4885
static __shimcall__
4886
unsigned int conexant_hsfmodem_OsHdaCodecGetSubsystemId(PHDAOSHAL pHdaOsHal)
4887
{
4888
        return ((struct hda_codec *)pHdaOsHal->hda_codec)->subsystem_id;
4889
}
4890
4891
static __shimcall__
4892
unsigned int conexant_hsfmodem_OsHdaCodecGetRevisionId(PHDAOSHAL pHdaOsHal)
4893
{
4894
        return ((struct hda_codec *)pHdaOsHal->hda_codec)->revision_id;
4895
}
4896
4897
static __shimcall__
4898
unsigned int conexant_hsfmodem_OsHdaCodecRead(PHDAOSHAL pHdaOsHal, unsigned short nid, int direct, unsigned int verb, unsigned int para)
4899
{
4900
#if 1
4901
        return snd_hda_codec_read((struct hda_codec *)pHdaOsHal->hda_codec, nid, direct, verb, para);
4902
#else
4903
        unsigned int res;
4904
4905
        res = snd_hda_codec_read((struct hda_codec *)pHdaOsHal->hda_codec, nid, direct, verb, para);
4906
4907
        printk(KERN_DEBUG"%s: nid=%x direct=%d verb=0x%x para=0x%x res=0x%08x\n", __FUNCTION__, nid, direct, verb, para, res);
4908
4909
        return res;
4910
#endif
4911
}
4912
4913
static __shimcall__
4914
unsigned int conexant_hsfmodem_OsHdaCodecWallclock(PHDAOSHAL pHdaOsHal)
4915
{
4916
        return snd_hda_codec_wallclock((struct hda_codec *)pHdaOsHal->hda_codec);
4917
}
4918
4919
static __shimcall__
4920
void conexant_hsfmodem_OsHdaCodecSetEventCallback(PHDAOSHAL pHdaOsHal, void (*cbHdaEvent)(void *Context, unsigned int res), void *cbHdaEventContext, unsigned char *cbHdaTag)
4921
{
4922
        struct conexant_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec;
4923
4924
        *cbHdaTag = ((struct hda_codec *)pHdaOsHal->hda_codec)->mfg;
4925
4926
        spec->modem_cbHdaTag = *cbHdaTag;
4927
        spec->modem_cbHdaEventContext = cbHdaEventContext;
4928
        spec->modem_cbHdaEvent = (void*)cbHdaEvent;
4929
}
4930
4931
static __shimcall__
4932
void conexant_hsfmodem_OsHdaCodecClearEventCallback(PHDAOSHAL pHdaOsHal, unsigned char cbHdaTag)
4933
{
4934
        struct conexant_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec;
4935
4936
        if(spec) {
4937
                spec->modem_cbHdaEvent = NULL;
4938
                spec->modem_cbHdaEventContext = NULL;
4939
                spec->modem_cbHdaTag = 0;
4940
        }
4941
}
4942
4943
#include <sound/pcm_params.h>
4944
4945
static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
4946
{
4947
        struct snd_interval t;
4948
        t.empty = 0;
4949
        t.min = t.max = val;
4950
        t.openmin = t.openmax = 0;
4951
        t.integer = 1;
4952
        return snd_interval_refine(i, &t);
4953
}
4954
4955
static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
4956
                                 snd_pcm_hw_param_t var, unsigned int val,
4957
                                 int dir)
4958
{
4959
        int changed;
4960
        if (hw_is_mask(var)) {
4961
                struct snd_mask *m = hw_param_mask(params, var);
4962
                if (val == 0 && dir < 0) {
4963
                        changed = -EINVAL;
4964
                        snd_mask_none(m);
4965
                } else {
4966
                        if (dir > 0)
4967
                                val++;
4968
                        else if (dir < 0)
4969
                                val--;
4970
                        changed = snd_mask_refine_set(hw_param_mask(params, var), val);
4971
                }
4972
        } else if (hw_is_interval(var)) {
4973
                struct snd_interval *i = hw_param_interval(params, var);
4974
                if (val == 0 && dir < 0) {
4975
                        changed = -EINVAL;
4976
                        snd_interval_none(i);
4977
                } else if (dir == 0)
4978
                        changed = snd_interval_refine_set(i, val);
4979
                else {
4980
                        struct snd_interval t;
4981
                        t.openmin = 1;
4982
                        t.openmax = 1;
4983
                        t.empty = 0;
4984
                        t.integer = 0;
4985
                        if (dir < 0) {
4986
                                t.min = val - 1;
4987
                                t.max = val;
4988
                        } else {
4989
                                t.min = val;
4990
                                t.max = val+1;
4991
                        }
4992
                        changed = snd_interval_refine(i, &t);
4993
                }
4994
        } else
4995
                return -EINVAL;
4996
        if (changed) {
4997
                params->cmask |= 1 << var;
4998
                params->rmask |= 1 << var;
4999
        }
5000
        return changed;
5001
}
5002
5003
static int conexant_modem_snd_pcm_change_params(struct snd_pcm_substream *substream, int hw_param_buffer_bytes)
5004
{
5005
        struct snd_pcm_hw_params *sparams;
5006
        int err;
5007
5008
        sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
5009
        if (/*!params ||*/ !sparams) {
5010
                return -ENOMEM;
5011
        }
5012
5013
        _snd_pcm_hw_params_any(sparams);
5014
        _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
5015
                              hw_param_buffer_bytes, 0);
5016
5017
        snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
5018
5019
        if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) {
5020
                printk(KERN_ERR"%s: SNDRV_PCM_IOCTL_HW_PARAMS failed (%d)\n", __FUNCTION__, err);
5021
                //return err;
5022
        }
5023
5024
        return 0;
5025
}
5026
5027
static int conexant_modem_snd_pcm_prepare_substream(PHDAOSHAL pHdaOsHal, struct snd_pcm_substream *substream)
5028
{
5029
        int err;
5030
        struct conexant_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec;
5031
5032
        if(spec->modem_do_prepare[substream->stream]) {
5033
                err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
5034
                if (err < 0) {
5035
                        printk(KERN_ERR"%s: SNDRV_PCM_IOCTL_PREPARE failed (%d)\n", __FUNCTION__, err);
5036
                        return err;
5037
                }
5038
                spec->modem_do_prepare[substream->stream] = 0;
5039
        }
5040
5041
        return 0;
5042
}
5043
5044
static __shimcall__
5045
int conexant_hsfmodem_OsHdaCodecOpenDMA(PHDAOSHAL pHdaOsHal, int hw_param_buffer_bytes, void **ppPlaybackStream, void **ppCaptureStream)
5046
{
5047
        int i, err;
5048
        struct hda_codec *codec = (struct hda_codec *)pHdaOsHal->hda_codec;
5049
        struct hda_pcm *info = codec->pcm_info;
5050
        struct snd_pcm *pcm;
5051
        struct conexant_spec *spec = codec->spec;
5052
5053
        struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
5054
        static struct file fil;
5055
5056
        for(i = 0; i < codec->num_pcms && info[i].pcm_type != HDA_PCM_TYPE_MODEM; i++);
5057
        if(i == codec->num_pcms) {
5058
                printk(KERN_ERR"%s: modem pcm not found\n", __FUNCTION__);
5059
                return -ENOENT;
5060
        }
5061
        pcm = info[i].pcm;
5062
5063
        if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_PLAYBACK, &fil, &psubstream)) < 0) {
5064
                printk(KERN_ERR"%s: snd_pcm_open_substream STREAM_PLAYBACK failed (%d)\n", __FUNCTION__, err);
5065
                return err;
5066
        }
5067
5068
        if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_CAPTURE, &fil, &csubstream)) < 0) {
5069
                printk(KERN_ERR"%s: snd_pcm_open_substream STREAM_CAPTURE failed (%d)\n", __FUNCTION__, err);
5070
                return err;
5071
        }
5072
5073
        err = conexant_modem_snd_pcm_change_params(psubstream, hw_param_buffer_bytes);
5074
        if (err < 0) {
5075
                printk(KERN_ERR"%s: conexant_modem_snd_pcm_change_params STREAM_PLAYBACK failed (%d)\n", __FUNCTION__, err);
5076
        }
5077
5078
        err = conexant_modem_snd_pcm_change_params(csubstream, hw_param_buffer_bytes);
5079
        if (err < 0) {
5080
                printk(KERN_ERR"%s: conexant_modem_snd_pcm_change_params STREAM_CAPTURE failed (%d)\n", __FUNCTION__, err);
5081
        }
5082
5083
#if 0
5084
        printk(KERN_DEBUG"%s: psubstream=%p dma_buffer_p=%p area=%p addr=0x%lx bytes=%d\n", __FUNCTION__,
5085
                        psubstream,
5086
                        psubstream->runtime->dma_buffer_p,
5087
                        psubstream->runtime->dma_area,
5088
                        (unsigned long)psubstream->runtime->dma_addr,
5089
                        psubstream->runtime->dma_bytes);
5090
5091
        printk(KERN_DEBUG"%s: csubstream=%p dma_buffer_p=%p area=%p addr=0x%lx bytes=%d\n", __FUNCTION__,
5092
                        csubstream,
5093
                        csubstream->runtime->dma_buffer_p,
5094
                        csubstream->runtime->dma_area,
5095
                        (unsigned long)csubstream->runtime->dma_addr,
5096
                        csubstream->runtime->dma_bytes);
5097
#endif
5098
5099
        spec->modem_do_prepare[psubstream->stream] = 1;
5100
        spec->modem_do_prepare[csubstream->stream] = 1;
5101
5102
        if ((err = conexant_modem_snd_pcm_prepare_substream(pHdaOsHal, psubstream)) < 0)
5103
                return err;
5104
5105
        if ((err = conexant_modem_snd_pcm_prepare_substream(pHdaOsHal, csubstream)) < 0)
5106
                return err;
5107
5108
        *ppPlaybackStream = psubstream;
5109
        *ppCaptureStream = csubstream;
5110
5111
        return 0;
5112
}
5113
5114
static void conexant_modem_snd_pcm_close_stream(struct snd_pcm_substream *substream)
5115
{
5116
#if SNDRV_PCM_VERSION <= SNDRV_PROTOCOL_VERSION(2, 0, 7)
5117
        snd_pcm_stream_lock_irq(substream);
5118
        if (snd_pcm_running(substream))
5119
                snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
5120
        snd_pcm_stream_unlock_irq(substream);
5121
5122
        if (substream->ops->hw_free != NULL)
5123
                substream->ops->hw_free(substream);
5124
5125
        substream->ops->close(substream);
5126
#endif
5127
        //printk(KERN_DEBUG"%s: substream=%p refcount=%d\n", __FUNCTION__, substream, substream->ref_count);
5128
        snd_pcm_release_substream(substream);
5129
}
5130
5131
static __shimcall__
5132
void conexant_hsfmodem_OsHdaCodecCloseDMA(PHDAOSHAL pHdaOsHal, void *pPlaybackStream, void *pCaptureStream)
5133
{
5134
        //printk(KERN_DEBUG"%s: pHdaOsHal=%p pPlaybackStream=%p pCaptureStream=%p\n", __FUNCTION__, pHdaOsHal, pPlaybackStream, pCaptureStream);
5135
        if(pHdaOsHal) {
5136
                if(pPlaybackStream)
5137
                        conexant_modem_snd_pcm_close_stream(pPlaybackStream);
5138
                if(pCaptureStream)
5139
                        conexant_modem_snd_pcm_close_stream(pCaptureStream);
5140
        }
5141
}
5142
5143
 static __shimcall__
5144
void conexant_hsfmodem_OsHdaCodecDMAInfo(PHDAOSHAL pHdaOsHal, void *Stream, unsigned char *StreamID, unsigned long *FifoSize, short unsigned int **ppBufAddr)
5145
{
5146
        struct conexant_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec;
5147
        struct snd_pcm_substream *substream = (struct snd_pcm_substream *)Stream;
5148
5149
#if 0
5150
        printk(KERN_DEBUG"%s: substream=%p stream=%u id/tag=%u fifo_size=%u bufAddr=%p\n", __FUNCTION__,
5151
                        substream,
5152
                        substream->stream,
5153
                        spec->modem_stream_tags[substream->stream],
5154
                        substream->runtime->hw.fifo_size,
5155
                        substream->runtime->dma_area);
5156
#endif
5157
5158
        *StreamID = spec->modem_stream_tags[substream->stream];
5159
        *FifoSize = substream->runtime->hw.fifo_size; // XXX
5160
        *ppBufAddr = (short unsigned int *)substream->runtime->dma_area;
5161
}
5162
5163
static __shimcall__
5164
int conexant_hsfmodem_OsHdaCodecSetDMAState(PHDAOSHAL pHdaOsHal, OSHDA_STREAM_STATE streamState, void *pPlaybackStream, void *pCaptureStream)
5165
{
5166
        struct conexant_spec *spec = ((struct hda_codec *)pHdaOsHal->hda_codec)->spec;
5167
        struct snd_pcm_substream *psubstream = (struct snd_pcm_substream *)pPlaybackStream;
5168
        struct snd_pcm_substream *csubstream = (struct snd_pcm_substream *)pCaptureStream;
5169
        int err = 0, cmd;
5170
        unsigned long flags, flags2;
5171
5172
        switch(streamState) {
5173
                case OsHdaStreamStateRun:
5174
//                      printk(KERN_DEBUG"%s: Run\n", __FUNCTION__);
5175
                        if ((err = conexant_modem_snd_pcm_prepare_substream(pHdaOsHal, psubstream)) < 0)
5176
                                return err;
5177
                        if ((err = conexant_modem_snd_pcm_prepare_substream(pHdaOsHal, csubstream)) < 0)
5178
                                return err;
5179
5180
                        cmd = SNDRV_PCM_IOCTL_START;
5181
                        psubstream->runtime->start_threshold = 1;
5182
                        psubstream->runtime->stop_threshold = psubstream->runtime->boundary;
5183
                        csubstream->runtime->start_threshold = 1;
5184
                        csubstream->runtime->stop_threshold = csubstream->runtime->boundary;
5185
                        break;
5186
                case OsHdaStreamStateStop:
5187
//                      printk(KERN_DEBUG"%s: Stop\n", __FUNCTION__);
5188
                        cmd = SNDRV_PCM_IOCTL_DROP;
5189
                        break;
5190
                case OsHdaStreamStateReset:
5191
//                      printk(KERN_DEBUG"%s: Reset\n", __FUNCTION__);
5192
                        cmd = SNDRV_PCM_IOCTL_RESET;
5193
                        psubstream->runtime->start_threshold = psubstream->runtime->boundary;
5194
                        csubstream->runtime->start_threshold = csubstream->runtime->boundary;
5195
                        break;
5196
                default:
5197
                        printk(KERN_ERR"%s: unknown state %d\n", __FUNCTION__, streamState);
5198
                        return -ENOSYS;
5199
        }
5200
5201
        switch(cmd) {
5202
                case SNDRV_PCM_IOCTL_START:
5203
                        snd_pcm_stream_lock_irqsave(psubstream, flags);
5204
                        snd_pcm_stream_lock_irqsave(csubstream, flags2);
5205
                        psubstream->ops->trigger(psubstream, SNDRV_PCM_TRIGGER_START);
5206
                        csubstream->ops->trigger(csubstream, SNDRV_PCM_TRIGGER_START);
5207
                        snd_pcm_stream_unlock_irqrestore(csubstream, flags2);
5208
                        snd_pcm_stream_unlock_irqrestore(psubstream, flags);
5209
                        break;
5210
                case SNDRV_PCM_IOCTL_DROP:
5211
                        snd_pcm_stream_lock_irqsave(psubstream, flags);
5212
                        snd_pcm_stream_lock_irqsave(csubstream, flags2);
5213
                        psubstream->runtime->start_threshold = psubstream->runtime->boundary;
5214
                        csubstream->runtime->start_threshold = csubstream->runtime->boundary;
5215
                        psubstream->ops->trigger(psubstream, SNDRV_PCM_TRIGGER_STOP);
5216
                        csubstream->ops->trigger(csubstream, SNDRV_PCM_TRIGGER_STOP);
5217
                        snd_pcm_stream_unlock_irqrestore(csubstream, flags2);
5218
                        snd_pcm_stream_unlock_irqrestore(psubstream, flags);
5219
                        break;
5220
                case SNDRV_PCM_IOCTL_RESET:
5221
                        //psubstream->ops->trigger(psubstream, SNDRV_PCM_TRIGGER_STOP);
5222
                        //csubstream->ops->trigger(csubstream, SNDRV_PCM_TRIGGER_STOP);
5223
                        /*FALLTHROUGH*/
5224
                default:
5225
                        err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
5226
                        if (err < 0) {
5227
                                printk(KERN_ERR"%s: snd_pcm_kernel_ioctl (playback) failed (%d)\n", __FUNCTION__, err);
5228
                        }
5229
5230
                        err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
5231
                        if (err < 0) {
5232
                                printk(KERN_ERR"%s: snd_pcm_kernel_ioctl (capture) failed (%d)\n", __FUNCTION__, err);
5233
                        }
5234
                        break;
5235
        }
5236
        if(cmd != SNDRV_PCM_IOCTL_START) {
5237
                spec->modem_do_prepare[psubstream->stream] = 1;
5238
                spec->modem_do_prepare[csubstream->stream] = 1;
5239
        }
5240
 
5241
        return err;
5242
}
5243
5244
static __shimcall__
5245
unsigned long conexant_hsfmodem_OsHdaCodecGetDMAPos(PHDAOSHAL pHdaOsHal, void *Stream)
5246
{
5247
        struct hda_codec *codec = (struct hda_codec *)pHdaOsHal->hda_codec;
5248
        struct snd_pcm_substream *substream = (struct snd_pcm_substream *)Stream;
5249
        int ret;
5250
5251
        if(codec->bus->ops.get_linkpos)
5252
                ret = codec->bus->ops.get_linkpos(substream);
5253
        else
5254
                ret = frames_to_bytes(substream->runtime, substream->ops->pointer(substream));
5255
 
5256
        //printk(KERN_DEBUG"%s: substream=%p pos=%ld, ret=%d\n", __FUNCTION__, substream, pos, ret);
5257
5258
        return ret;
5259
}
5260
5261
static void *conexant_hsfmodem_interface_funcs[] = {
5262
        conexant_hsfmodem_OsHdaCodecGetAddr,
5263
        conexant_hsfmodem_OsHdaCodecGetVendorId,
5264
        conexant_hsfmodem_OsHdaCodecGetSubsystemId,
5265
        conexant_hsfmodem_OsHdaCodecGetRevisionId,
5266
        conexant_hsfmodem_OsHdaCodecRead,
5267
        conexant_hsfmodem_OsHdaCodecWallclock,
5268
        conexant_hsfmodem_OsHdaCodecSetEventCallback,
5269
        conexant_hsfmodem_OsHdaCodecClearEventCallback,
5270
        conexant_hsfmodem_OsHdaCodecOpenDMA,
5271
        conexant_hsfmodem_OsHdaCodecCloseDMA,
5272
        conexant_hsfmodem_OsHdaCodecDMAInfo,
5273
        conexant_hsfmodem_OsHdaCodecSetDMAState,
5274
        conexant_hsfmodem_OsHdaCodecGetDMAPos,
5275
        NULL
5276
};
5277
5278
/*
5279
 */
5280
4565
static const struct hda_codec_preset snd_hda_preset_conexant[] = {
5281
static const struct hda_codec_preset snd_hda_preset_conexant[] = {
4566
	{ .id = 0x14f15045, .name = "CX20549 (Venice)",
5282
	{ .id = 0x14f15045, .name = "CX20549 (Venice)",
4567
	  .patch = patch_cxt5045 },
5283
	  .patch = patch_cxt5045 },
Lines 4579-4584 Link Here
4579
	  .patch = patch_cxt5066 },
5295
	  .patch = patch_cxt5066 },
4580
	{ .id = 0x14f1506c, .name = "CX20588",
5296
	{ .id = 0x14f1506c, .name = "CX20588",
4581
	  .patch = patch_cxt5066 },
5297
	  .patch = patch_cxt5066 },
5298
        { .id = 0x14f12bfa, .mfg = 2, .name = "HSF",
5299
          .patch = patch_cxthsfmodem },
5300
        { .id = 0x14f12c06, .mfg = 2, .name = "HSF",
5301
          .patch = patch_cxthsfmodem },
5302
        { .id = 0x14f10000, .mask = 0xffff0000, .mfg = 2, .name = "HSF",
5303
          .patch = patch_cxthsfmodem },
4582
	{ .id = 0x14f1506e, .name = "CX20590",
5304
	{ .id = 0x14f1506e, .name = "CX20590",
4583
	  .patch = patch_cxt5066 },
5305
	  .patch = patch_cxt5066 },
4584
	{ .id = 0x14f15097, .name = "CX20631",
5306
	{ .id = 0x14f15097, .name = "CX20631",
Lines 4613-4618 Link Here
4613
MODULE_ALIAS("snd-hda-codec-id:14f15067");
5335
MODULE_ALIAS("snd-hda-codec-id:14f15067");
4614
MODULE_ALIAS("snd-hda-codec-id:14f15068");
5336
MODULE_ALIAS("snd-hda-codec-id:14f15068");
4615
MODULE_ALIAS("snd-hda-codec-id:14f15069");
5337
MODULE_ALIAS("snd-hda-codec-id:14f15069");
5338
MODULE_ALIAS("snd-hda-codec-id:14f12bfa");
5339
MODULE_ALIAS("snd-hda-codec-id:14f12c06");
5340
MODULE_ALIAS("snd-hda-codec-id:14f1*");
4616
MODULE_ALIAS("snd-hda-codec-id:14f1506c");
5341
MODULE_ALIAS("snd-hda-codec-id:14f1506c");
4617
MODULE_ALIAS("snd-hda-codec-id:14f1506e");
5342
MODULE_ALIAS("snd-hda-codec-id:14f1506e");
4618
MODULE_ALIAS("snd-hda-codec-id:14f15097");
5343
MODULE_ALIAS("snd-hda-codec-id:14f15097");
Lines 4628-4634 Link Here
4628
MODULE_ALIAS("snd-hda-codec-id:14f15111");
5353
MODULE_ALIAS("snd-hda-codec-id:14f15111");
4629
5354
4630
MODULE_LICENSE("GPL");
5355
MODULE_LICENSE("GPL");
4631
MODULE_DESCRIPTION("Conexant HD-audio codec");
5356
MODULE_DESCRIPTION("Conexant HD-audio and modem codec");
4632
5357
4633
static struct hda_codec_preset_list conexant_list = {
5358
static struct hda_codec_preset_list conexant_list = {
4634
	.preset = snd_hda_preset_conexant,
5359
	.preset = snd_hda_preset_conexant,

Return to bug 351225