All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Alsa-user] chipset CX5530
       [not found] <20021201105428.2afa833d.jean-marc.harang@laposte.net>
@ 2002-12-02  8:33 ` Clemens Ladisch
  2002-12-02  8:56   ` Takashi Iwai
  0 siblings, 1 reply; 9+ messages in thread
From: Clemens Ladisch @ 2002-12-02  8:33 UTC (permalink / raw)
  To: Jean-Marc Harang; +Cc: alsa-user, alsa-devel

Jean-marc Harang wrote:
> I search informations about this chipset (drivers, users feedback, etc...).

http://groups.google.com/groups?threadm=veofj0z47t.fsf@inigo.sthlm.cendio.se

There is an ALSA package containing a Geode driver at
<http://www.gctglobal.com/Download/alsa-geode.tar.gz>, but it's based on
0.5.10b. However, there seems to be some documentation (in a Word file),
so it should be possible to port it to 0.9.x.

Now you only need to find somebody to do the port. :-)


HTH
Clemens



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Alsa-user] chipset CX5530
  2002-12-02  8:33 ` [Alsa-user] chipset CX5530 Clemens Ladisch
@ 2002-12-02  8:56   ` Takashi Iwai
  2002-12-02  9:11     ` Alamy Liu
  0 siblings, 1 reply; 9+ messages in thread
From: Takashi Iwai @ 2002-12-02  8:56 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: Jean-Marc Harang, alsa-user, alsa-devel

At Mon, 02 Dec 2002 09:33:03 +0100 (MET),
Clemens Ladisch wrote:
> 
> Jean-marc Harang wrote:
> > I search informations about this chipset (drivers, users feedback, etc...).
> 
> http://groups.google.com/groups?threadm=veofj0z47t.fsf@inigo.sthlm.cendio.se
> 
> There is an ALSA package containing a Geode driver at
> <http://www.gctglobal.com/Download/alsa-geode.tar.gz>, but it's based on
> 0.5.10b. However, there seems to be some documentation (in a Word file),
> so it should be possible to port it to 0.9.x.
> 
> Now you only need to find somebody to do the port. :-)

the code is written quite normally, and i guess one can port fairly
straightforwardly.  perhaps one or two days job.

if someone wants to learn how to alsa driver, it would be a good
practice.
any volunteer?


Takashi


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Alsa-user] chipset CX5530
  2002-12-02  8:56   ` Takashi Iwai
@ 2002-12-02  9:11     ` Alamy Liu
  2002-12-02 10:50       ` Takashi Iwai
  0 siblings, 1 reply; 9+ messages in thread
From: Alamy Liu @ 2002-12-02  9:11 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-user, alsa-devel

I would like to take it.  May I ?
But I need guidance.

Alamy Liu

Takashi Iwai wrote:

>At Mon, 02 Dec 2002 09:33:03 +0100 (MET),
>Clemens Ladisch wrote:
>  
>
>>Jean-marc Harang wrote:
>>    
>>
>>>I search informations about this chipset (drivers, users feedback, etc...).
>>>      
>>>
>>http://groups.google.com/groups?threadm=veofj0z47t.fsf@inigo.sthlm.cendio.se
>>
>>There is an ALSA package containing a Geode driver at
>><http://www.gctglobal.com/Download/alsa-geode.tar.gz>, but it's based on
>>0.5.10b. However, there seems to be some documentation (in a Word file),
>>so it should be possible to port it to 0.9.x.
>>
>>Now you only need to find somebody to do the port. :-)
>>    
>>
>
>the code is written quite normally, and i guess one can port fairly
>straightforwardly.  perhaps one or two days job.
>
>if someone wants to learn how to alsa driver, it would be a good
>practice.
>any volunteer?
>
>
>Takashi
>
>
>-------------------------------------------------------
>This sf.net email is sponsored by:ThinkGeek
>Welcome to geek heaven.
>http://thinkgeek.com/sf
>_______________________________________________
>Alsa-devel mailing list
>Alsa-devel@lists.sourceforge.net
>https://lists.sourceforge.net/lists/listinfo/alsa-devel
>
>
>  
>




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Alsa-user] chipset CX5530
  2002-12-02  9:11     ` Alamy Liu
@ 2002-12-02 10:50       ` Takashi Iwai
  2002-12-02 16:17         ` Patrick Shirkey
  2002-12-02 18:35         ` Part 2 (Re: [Alsa-user] chipset CX5530) Takashi Iwai
  0 siblings, 2 replies; 9+ messages in thread
From: Takashi Iwai @ 2002-12-02 10:50 UTC (permalink / raw)
  To: Alamy Liu; +Cc: alsa-devel

Hi,

(removed alsa-users from Cc since focused on the development only.)

At Mon, 02 Dec 2002 17:11:20 +0800,
Alamy Liu wrote:
> 
> I would like to take it.  May I ?
> But I need guidance.

the geode driver seems having the followng additional files to the
0.5.10b driver tree:

- include/geode.h
- cards/card-geode.c
- lowlevel/pci/geode.c
- lowlevel/pci/duraudio.c
- lowlevel/pci/5530_def.h
- lowlevel/pci/5530_glb.h
- lowlevel/pci/os_inc.h

on the alsa 0.9.0 tree, you should create a driver code either into a
single file

- pci/geode.c

or files under sub-directory

- pci/geode/*.[ch]

please note that even the card-specific header files should go into
this sub-directory unless they need to be exported to user-space.


after i took a further look at the codes, i found that there are many
unnecessary parts in the files above.
especially, most of duraudio.c shouldn't be used.  it's evil.
also, the macros in os_inc.h should be expanded, i.e. the standard 
functions instead of redefined macro should be used.
because of these things, the porting may take longer than i
expected...


anyway, let me explain the first step.

the basic structure of the code would be as same as other pci
drivers.  please check some driver sources.  for example, es1938.c or 
maestro3.c are good example.  both of them have the sources on 0.5.x
tree, so you can compare the differences.

you'll have *_init() function just calling pci_module_init() to
register the pci_driver table which contains name, id_table, probe and
remove pointers.
also, *_exit() function to call pci_unregister_driver().

the real init part is done in *_probe() callback.
there, check and increment the device index at first.
then create a card: snd_card_new().

the chip-specific data are stored in a chip record.
this can be allocated in two ways.

1) allocating via snd_card_new().
   you can pass the extra-data-length to the 4th argument of
   snd_card_new(), i.e.
	card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(geode_t))
   whether geode_t is the chip record.
   in return, the allocated record can be acceseed as
	geode_t *chip = (geode_t *)card->private_data;

   with this method, you don't have to allocate twice.  but you cannot
   use "magic-cast" for this record pointer, instead.  (see below)

2) allocating an extra device.
   after allocating a card instance via snd_card_new() (with NULL on
   the 4th arg), call snd_magic_kcalloc().

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
	....
	chip = snd_magic_kcalloc(geode_t, 0, GFP_KERNEL);
	chip->card = card;
	...
    you need to define a magic-value for geode_t (in include/sndmagic.h)
	#define snd_usb_midi_in_endpoint_t_magic	0xa15a4501
    the value is arbitrary but should be unique.

    initialize the fields, and register this chip record as a lowlevel
    device with a specifed ops,

	static snd_device_ops_t ops = {
		.dev_free =	snd_geode_dev_free,
	};
	snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);

    snd_geode_dev_free() is the device-destructor, which will call

	static int snd_geode_dev_free(snd_device_t *device)
	{
		geode_t *chip = snd_magic_cast(geode_t, device->device_data, return -ENXIO);
		return snd_geode_free(chip);
	}

   where snd_geode_free() is the real destructor.


what is the advantage of the second method?
as mentioned above, the second method allows a "magic-cast" for
geode_t.  if you have a void pointer (such like pcm->private_data),
the pointer type is unknown at the compile time, and you cannot know
even if a wrong pointer is passed.  the magic-cast checks the pointer
type at the runtime, so it's good for debugging.

for casting a pointer, do like this:

	geode_t *chip = snd_magic_cast(geode_t, source_pointer, action);

source_pointer is the pointer to be casted (e.g. pcm->private_data)
action is the action to do if the cast fails (e.g. return -EINVAL).

now you can check and allocate resources.
don't forget to call pci_enable_device() before allocating resources.
also you have to call pci_set_dma_mask() with 28bit mask
(0x0fffffff) for geode chips.

on 0.9.0, you don't need allocate DMA for PCI like 0.5.x.
allocation of ports and irqs are done via standard kernel functions.
unlike 0.5.x., there are no helpers for that.
and these resources must be released in the destructor function (see
below).

when the resources are allocated, then we can create pcm and mixer
stuffs.  but let's take them later on and write a destructor at
first.

the role of destructor is simple: disable the hardware (if already
activated) and release the resources.
for releasing the resource, "check-and-release" method is a safer way.
i.e.
	
	static int snd_geode_free(geode_t *chip)
	{
		if (chip->res_port) {
			release_resource(chip->res_port);
			kfree_nocheck(chip->res_port);
		}
		if (chip->irq >= 0)
			free_irq(chip->irq, (void *)chip);
		snd_magic_kfree(chip);
		return 0;
	}

as you can see, the i/o resources are also to be freed via
kfree_nocheck() after release_resource() is called.


now, let's finish the pci_driver data.
write a pci_device_id table for this chipset,

	static struct pci_device_id snd_geode_ids[] __devinitdata = {
	        { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_UNICORN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
	        { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CENTAURUS, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
	        { PCI_VENDOR_ID_NSC, PCI_DEVICE_ID_CENTAURUS, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
	        { PCI_VENDOR_ID_NSC, PCI_DEVICE_ID_SCORPIUS, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
		{ 0, }
	};
	MODULE_DEVICE_TABLE(pci, snd_geode_ids);

and

	static struct pci_driver driver = {
		.name = "NSC/Cyrix Geode",
		.id_table = snd_geode_ids,
		.probe = snd_geode_probe,
		.remove = __devexit_p(snd_geode_remove),
	};


	static int __init alsa_card_geode_init(void)
	{
		int err;

		if ((err = pci_module_init(&driver)) < 0) {
#ifdef MODULE
			printk(KERN_ERR "NSC/Cyrix Geode soundcard not found or device busy\n");
#endif
			return err;
		}
		return 0;
	}

	static void __exit alsa_card_geode_exit(void)
	{
		pci_unregister_driver(&driver);
	}

	module_init(alsa_card_geode_init)
	module_exit(alsa_card_geode_exit)


you can at least comple and build the module now (although not
functional yet :)
let's proceed to the pcm and ac97 part at next...


ciao,

Takashi


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Alsa-user] chipset CX5530
  2002-12-02 10:50       ` Takashi Iwai
@ 2002-12-02 16:17         ` Patrick Shirkey
  2002-12-02 17:24           ` usb quattro not recording Patrick Shirkey
  2002-12-02 18:35         ` Part 2 (Re: [Alsa-user] chipset CX5530) Takashi Iwai
  1 sibling, 1 reply; 9+ messages in thread
From: Patrick Shirkey @ 2002-12-02 16:17 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

That's very informative Takashi.

I have stored it for inclusion in the alsa-docs at a later stage when 
this information is more fully explained.


-- 
Patrick Shirkey - Boost Hardware Ltd.
For the discerning hardware connoisseur
Http://www.boosthardware.com
Http://www.djcj.org - The Linux Audio Users guide
========================================

Being on stage with the band in front of crowds shouting, "Get off! No! 
We want normal music!", I think that was more like acting than anything 
I've ever done.

Goldie, 8 Nov, 2002
The Scotsman



-------------------------------------------------------
This SF.net email is sponsored by: Get the new Palm Tungsten T 
handheld. Power & Color in a compact size! 
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en

^ permalink raw reply	[flat|nested] 9+ messages in thread

* usb quattro not recording
  2002-12-02 16:17         ` Patrick Shirkey
@ 2002-12-02 17:24           ` Patrick Shirkey
  2002-12-03 20:56             ` Patrick Shirkey
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick Shirkey @ 2002-12-02 17:24 UTC (permalink / raw)
  Cc: alsa-devel

Much to my surprise the quattro has stopped being able to record with 
cvs from Nov 27 2002 and also a fresh checkout today.

Neither pcm devices are able to capture.

Playback is fine however.

It might be telling that jack hangs here in capture only mode:

----
jackd -d alsa -d quattro1 -C
jackd 0.40.0
Copyright 2001-2002 Paul Davis and others.
jackd comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details

loading driver ..
creating alsa driver ... quattro1|1024|2|48000|swmon
starting engine

----

$ cat /proc/asound/card2/pcm0c/
info  oss   sub0
$ cat /proc/asound/card2/pcm0c/info
card: 2
device: 0
subdevice: 0
stream: CAPTURE
id: USB Audio
name: USB Audio
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
$ cat /proc/asound/card2/pcm0c/oss
$ cat /proc/asound/card2/pcm0c/sub0/
cat: /proc/asound/card2/pcm0c/sub0/: Is a directory
$ cat /proc/asound/card2/pcm0c/sub0/
hw_params  info       prealloc   status     sw_params
$ cat /proc/asound/card2/pcm0c/sub0/hw_params
closed
$ cat /proc/asound/card2/pcm0c/sub0/info
card: 2
device: 0
subdevice: 0
stream: CAPTURE
id: USB Audio
name: USB Audio
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
$ cat /proc/asound/card2/pcm0c/sub0/prealloc
64
$ cat /proc/asound/card2/pcm0c/sub0/status
closed
$ cat /proc/asound/card2/pcm0c/sub0/sw_params
closed

----

How embarrasing. I thought I was recording on Friday night and told my 
friend we wouldn't need his MD. Now I have 4 hours of pure silence :(

-- 
Patrick Shirkey - Boost Hardware Ltd.
For the discerning hardware connoisseur
Http://www.boosthardware.com
Http://www.djcj.org - The Linux Audio Users guide
========================================

Being on stage with the band in front of crowds shouting, "Get off! No! 
We want normal music!", I think that was more like acting than anything 
I've ever done.

Goldie, 8 Nov, 2002
The Scotsman



-------------------------------------------------------
This SF.net email is sponsored by: Get the new Palm Tungsten T 
handheld. Power & Color in a compact size! 
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Part 2 (Re: [Alsa-user] chipset CX5530)
  2002-12-02 10:50       ` Takashi Iwai
  2002-12-02 16:17         ` Patrick Shirkey
@ 2002-12-02 18:35         ` Takashi Iwai
  1 sibling, 0 replies; 9+ messages in thread
From: Takashi Iwai @ 2002-12-02 18:35 UTC (permalink / raw)
  To: Alamy Liu; +Cc: alsa-devel

Hi,

let's start the second part of the alsa-driver-writing howto.

so far, i explained the basic flow of constructor and destructor of
the module.  i forgot to mention that the resource is most likely a
memory region, which is allocated via request_mem_region().

	typedef struct _snd_geode geode_t;
	struct _snd_geode {
		...
		unsigned long iobase_phys;
		unsigned long iobase_virt;
		struct resource *res_iobase;
	};

	chip->iobase_phys = pci_resource_start(pci, 0);
	if ((chip->res_iobase = request_mem_region(chip->iobase_phys, 512,
						"Geode")) == NULL) {
		snd_geode_free(chip);
		snd_printk(KERN_ERR "ERROR!\n");
		return -EBUSY;
	}
	chip->iobase_virt = (unsigned long)ioremap_nocache(chip->iobase_phys, 512);
	...

and it seems that geode uses a fixed irq 5.  i'm not sure whether it's
true.  anyway, the code will be like:

#define GEODE_IRQ	5
	if (request_irq(GEODE_IRQ, snd_geode_interrupt, SA_INTERRUPT|SA_SHIRQ, "Geode", (void *) chip)) {
		snd_geode_free(chip);
		snd_printk("unable to grab IRQ %d\n", GEODE_IRQ);
		return -EBUSY;
	}
	chip->irq = GEODE_IRQ;

and you need to write an interrupt handler,

	static void snd_geode_interrupt(int irq, void *dev_id, struct pt_regs *regs)
	{
		geode_t *chip = snd_magic_cast(geode_t, dev_id, return);
		...
	}

the destructor will be

	static int snd_geode_free(es1938_t *chip)
	{
		if (chip->iobase_virt)
			iounmap((void *)chip->iobase_virt);
		if (chip->res_iobase) {
			release_resource(chip->res_iobase);
			kfree_nocheck(chip->res_iobase);
		}
		if (chip->irq >= 0)
			free_irq(chip->irq, (void *)chip);
		snd_magic_kfree(chip);
		return 0;
	}


***

OK, let's rock to PCM stuff.

the pcm is allocated snd_pcm_new() function.
it would be better to create a constructor for pcm, namely,

	static int __devinit snd_geode_new_pcm(geode_t *chip)
	{
		snd_pcm_t *pcm;
		int err;

		if ((err = snd_pcm_new(chip->card, "Geode", 0, 1, 1, &pcm)) < 0) 
			return err;
		pcm->private_data = chip;
		strcpy(pcm->name, "Geode");
		chip->pcm = pcm;
		/* more to come here.. */
		return 0;
	}

the third argument (0) of snd_pcm_new is the index of this new pcm.
it begins from zero.
the fourth and fifth arguments are the number of substreams for
playback and capture.  here both 1 are given.
if a chip supports multiple playbacks or captures, you can specify
more numbers, but they must be handled properly in open/close, etc.

after the pcm is created, you need to set operators for the pcm
streams.

	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_geode_playback_ops);
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_geode_capture_ops);

the operators are defined typically like this:

	static snd_pcm_ops_t snd_geode_playback_ops = {
		.open =		snd_geode_playback_open,
		.close =	snd_geode_playback_close,
		.ioctl =	snd_pcm_lib_ioctl,
		.hw_params =	snd_geode_pcm_hw_params,
		.hw_free =	snd_geode_pcm_hw_free,
		.prepare =	snd_geode_pcm_prepare,
		.trigger =	snd_geode_pcm_trigger,
		.pointer =	snd_geode_pcm_pointer,
	};

each of callbacks is explained in the next section.

after setting the operators, pre-allocate the buffer.
simply call the following,

	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 64*1024);

it will allocate up to 64kB buffer as default.

... and the destructor?
not always necessary.  since the pcm device will be released by the
middle layer code automatically, you don't have to call destructor
explicitly.


***

ok, let me explain the detail of each pcm callback (ops).
all callbacks must return 0 if successful, or a negative number at any
error.
for retrieving the chip record from the given substream instance, you
can use the following macro.

	#define chip_t geode_t

	int xxx() {
		geode_t *chip = snd_pcm_substream_chip(substream);
		...
	}

it's expanded with a magic-cast, so the cast-error is automatically
checked.


* open callback

	static int snd_xxx_open(snd_pcm_substream_t *subs);

  this is called when a pcm substream is opened.
  at least, here you have to init the runtime hardware record.
  typically, this is done by like this:

	static int snd_xxx_open(snd_pcm_substream_t *substream)
	{
		geode_t *chip = snd_pcm_substream_chip(substream);
		snd_pcm_runtime_t *runtime = substream->runtime;

		runtime->hw = snd_geode_playback;
		return 0;
	}

  where snd_geode_playback is the pre-defined hardware record.

	static snd_pcm_hardware_t snd_geode_playback = {
		.info =		(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
				 SNDRV_PCM_INFO_MMAP_VALID),
		.formats =	SNDRV_PCM_FMTBIT_S16_LE,
		.rates =	SNDRV_PCM_RATE_8000_48000,
		.rate_min =	8000,
		.rate_max =	48000,
		.channels_min =		2,
		.channels_max =		2,
		.buffer_bytes_max =	32768,
		.period_bytes_min =	4096,
		.period_bytes_max =	32768,
		.periods_min =		1,
		.periods_max =		1024,
	};

  the similar struct exists on ALSA 0.5.x driver, so you can guess the
  values.

  the info field contains the type and capabilities of this pcm.
  here you have to specify the MMAP and interleaved format.
  MMAP_VALID and BLOCK_TRANSFER are specified for OSS mmap mode.
  usually both are set.

  formats field contains the bit-flags of supported formats.
  rates field contains the bit-flags of supported rates.
  the rate bits are defined only for typical rates.  if your chip
  supports unconventional rates, you need to set up the constraint
  manually (explained later).
  the other fields are self-explanatory.
  please note that here, both min/max buffer and period sizes are
  specifed in bytes.

  some drivers allocate the private instace for each pcm substream.
  it can be stored in runtime->private_data.  since it's a void
  pointer, you should use magic-kmalloc and magic-cast for such an
  object.  the allocated object must be released in the close
  callback below.


* close callback

	static int snd_xxx_close(snd_pcm_substream_t *subs);

  obviously, this is called at close.
  any private instance for a pcm substream will be released here.


* ioctl callback

  this is used for any special action to pcm ioctls.
  but usually you can pass a generic ioctl callback,
  snd_pcm_lib_ioctl.


* hw_params callback

  static int snd_xxx_hw_params(snd_pcm_substream_t * substream,
			       snd_pcm_hw_params_t * hw_params);

  (this and hw_free callbacks exist only on ALSA 0.9.0.)

  this is called when hw_params is set up by the application.
  many hardware set-up should be done in this callback, including the
  allocation of buffers.
  parameters to be initialized are retrieved by params_xxx() macros.
  for allocating a buffer, you can call a helper function,

	snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));

  note that this callback may be called multiple times.
  thus, you need to take care not to allocate many times!

  this callback is schedulable.  this is important, because the
  prepare callback is non-schedulable.  that is, mutex or any
  schedule-related functions are available only in hw_params
  callback.


* hw_free callback

  static int snd_xxx_hw_free(snd_pcm_substream_t * substream);

  this is called to release the resources allocated via hw_params.
  for example, releasing the buffer is done like

	snd_pcm_lib_free_pages(substream);

  note that this function may be called multiple times, too.
  keep track whether the resource was alreay released.


* prepare callback

  static int snd_xxx_prepare(snd_pcm_substream_t * substream);

  this callback is called when the pcm is "prepared".
  you can set the format type, sample rate, etc. here.

  as mentioned above, this callback is non-schedulable.
  i.e. you cannot use mutex in this callback.

  in this and the follwoing callbacks, you can refer to the values via
  runtime record.  for example, to get the current rate or format,
  access to runtime->rate or runtime->format, respectively.

  note that the period and the buffer sizes are stored in "frames".
  on ALSA world, 1 frame = channels * samples-size.
  for conversion between frames and bytes, you can use the helper
  functions, frames_to_bytes() and bytes_to_frames().

  be careful that this callback will be called many times at each set
  up, too.


* trigger callback

  static int snd_xxx_trigger(snd_pcm_substream_t * substream, int cmd);

  this is called when the pcm is started, stopped or paused.
  which action is specifed in the second argument:
    SNDRV_PCM_TRIGGER_START, SNDRV_PCM_TRIGGER_STOP.

  this callback is also non-schedulable.


* pointer callback

  static snd_pcm_uframes_t snd_xxx_pointer(snd_pcm_substream_t * substream)

  this callback is called when the PCM middle layer inquires the
  current h/w position on the buffer.
  the position must be returned in frames, from 0 to buffer_size - 1.
  (note that it's not in bytes like ALSA 0.5.x!)

  this is called usually when snd_pcm_period_elapsed() is called in
  the interrupt routine.  then the pcm middle layer updates the
  position and calculates the available space, and wakes up the
  sleeping poll threads, etc.

  this callback is also non-schedulable.


***

the major rest of pcm stuff is the interrupt handler.
the role of interrupt handler in the sound driver is to update the
buffer position and to tell the PCM middle layer when the buffer
position goes across the prescribed period size.
to inform this, call snd_pcm_period_elapsed() function.

there are several types of sound chips to generate the interrupts.

1) generates an interrupt at the period (fragment) boundary

  this is the most frequently found type.
  in this case, you can call snd_pcm_period_elapsed() at each
  interrupt.

2) high-frequent timer interrupts
   (e.g. es1968 or ymfpci drivers)

  check the current h/w position and accumulates the processed sample
  length.  when the accumulated size overcomes the period size,
  call snd_pcm_period_elapsed() and reset the accumulator.

in both cases, even if more than one period are elapsed, you don't
have to call snd_pcm_period_elapsed() many times.
call only once.  and the pcm layer will check the current h/w pointer
and update to the latest status.


***

i thought to explain about the hw_constraint in this section, but i'm
tired and hungry now - please allow me to postpone this and the
ac97-mixer stuff tomorrow :)


ciao,

Takashi


-------------------------------------------------------
This SF.net email is sponsored by: Get the new Palm Tungsten T 
handheld. Power & Color in a compact size! 
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: usb quattro not recording
  2002-12-02 17:24           ` usb quattro not recording Patrick Shirkey
@ 2002-12-03 20:56             ` Patrick Shirkey
  2002-12-05  2:42               ` Patrick Shirkey
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick Shirkey @ 2002-12-03 20:56 UTC (permalink / raw)
  Cc: alsa-devel

Patrick Shirkey wrote:
> Much to my surprise the quattro has stopped being able to record with 
> cvs from Nov 27 2002 and also a fresh checkout today.
> 

It's definitely broken as going back to the 18 November works. Damn, 
looks like I'll have to take the computer to the next gig too ;)


-- 
Patrick Shirkey - Boost Hardware Ltd.
For the discerning hardware connoisseur
Http://www.boosthardware.com
Http://www.djcj.org - The Linux Audio Users guide
========================================

Being on stage with the band in front of crowds shouting, "Get off! No! 
We want normal music!", I think that was more like acting than anything 
I've ever done.

Goldie, 8 Nov, 2002
The Scotsman



-------------------------------------------------------
This SF.net email is sponsored by: Microsoft Visual Studio.NET 
comprehensive development tool, built to increase your 
productivity. Try a free online hosted session at:
http://ads.sourceforge.net/cgi-bin/redirect.pl?micr0003en

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: usb quattro not recording
  2002-12-03 20:56             ` Patrick Shirkey
@ 2002-12-05  2:42               ` Patrick Shirkey
  0 siblings, 0 replies; 9+ messages in thread
From: Patrick Shirkey @ 2002-12-05  2:42 UTC (permalink / raw)
  Cc: alsa-devel

Patrick Shirkey wrote:
> Patrick Shirkey wrote:
> 
>> Much to my surprise the quattro has stopped being able to record with 
>> cvs from Nov 27 2002 and also a fresh checkout today.
>>
> 
> It's definitely broken as going back to the 18 November works. 
> 

After doing more testing it seems that the quattro requires that *both* 
pcms are initialised with the qinit util. Can someone tell me how to 
modify this so that hw:0,0 and hw:0,1 are both accessed please?

---------

/* program to prime an alsa device without sending data

Save as qinit.c and compile with:

         gcc -o qinit qinit.c -lasound -ldl -lm

*/


#include <alsa/asoundlib.h>

int main()
{
         snd_pcm_t *pcm;
         int err;
         snd_pcm_hw_params_t *hw;
         printf("Initialising quattro\n");
         err = snd_pcm_open(&pcm, "hw:0,0", SND_PCM_STREAM_PLAYBACK, 0);
         snd_pcm_hw_params_alloca(&hw);
         err = snd_pcm_hw_params_any(pcm, hw);
         err = snd_pcm_hw_params_set_access(pcm, hw, 
SND_PCM_ACCESS_RW_INTERLEAVED);
         err = snd_pcm_hw_params_set_format(pcm, hw, SND_PCM_FORMAT_S16_LE);
         err = snd_pcm_hw_params_set_rate(pcm, hw, 48000, 0);
         err = snd_pcm_hw_params_set_channels(pcm, hw, 2);
         err = snd_pcm_hw_params_set_period_size(pcm, hw, 512, 0);
         err = snd_pcm_hw_params_set_buffer_size(pcm, hw, 1024);
         err = snd_pcm_hw_params(pcm, hw);
         return err;
}

-----------
-- 
Patrick Shirkey - Boost Hardware Ltd.
For the discerning hardware connoisseur
Http://www.boosthardware.com
Http://www.djcj.org - The Linux Audio Users guide
========================================

Being on stage with the band in front of crowds shouting, "Get off! No! 
We want normal music!", I think that was more like acting than anything 
I've ever done.

Goldie, 8 Nov, 2002
The Scotsman



-------------------------------------------------------
This SF.net email is sponsored by: Microsoft Visual Studio.NET 
comprehensive development tool, built to increase your 
productivity. Try a free online hosted session at:
http://ads.sourceforge.net/cgi-bin/redirect.pl?micr0003en

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2002-12-05  2:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20021201105428.2afa833d.jean-marc.harang@laposte.net>
2002-12-02  8:33 ` [Alsa-user] chipset CX5530 Clemens Ladisch
2002-12-02  8:56   ` Takashi Iwai
2002-12-02  9:11     ` Alamy Liu
2002-12-02 10:50       ` Takashi Iwai
2002-12-02 16:17         ` Patrick Shirkey
2002-12-02 17:24           ` usb quattro not recording Patrick Shirkey
2002-12-03 20:56             ` Patrick Shirkey
2002-12-05  2:42               ` Patrick Shirkey
2002-12-02 18:35         ` Part 2 (Re: [Alsa-user] chipset CX5530) Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.