brintos

brintos / linux-shallow public Read only

0
0
Text · 45.9 KiB · 242bd7e Raw
1667 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Driver for Digigram pcxhr compatible soundcards4 *5 * main file with alsa callbacks6 *7 * Copyright (c) 2004 by Digigram <alsa@digigram.com>8 */9 10 11#include <linux/init.h>12#include <linux/interrupt.h>13#include <linux/slab.h>14#include <linux/pci.h>15#include <linux/dma-mapping.h>16#include <linux/delay.h>17#include <linux/module.h>18#include <linux/mutex.h>19 20#include <sound/core.h>21#include <sound/initval.h>22#include <sound/info.h>23#include <sound/control.h>24#include <sound/pcm.h>25#include <sound/pcm_params.h>26#include "pcxhr.h"27#include "pcxhr_mixer.h"28#include "pcxhr_hwdep.h"29#include "pcxhr_core.h"30#include "pcxhr_mix22.h"31 32#define DRIVER_NAME "pcxhr"33 34MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>, "35	      "Marc Titinger <titinger@digigram.com>");36MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING);37MODULE_LICENSE("GPL");38 39static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */40static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */41static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */42static bool mono[SNDRV_CARDS];				/* capture  mono only */43 44module_param_array(index, int, NULL, 0444);45MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");46module_param_array(id, charp, NULL, 0444);47MODULE_PARM_DESC(id, "ID string for Digigram " DRIVER_NAME " soundcard");48module_param_array(enable, bool, NULL, 0444);49MODULE_PARM_DESC(enable, "Enable Digigram " DRIVER_NAME " soundcard");50module_param_array(mono, bool, NULL, 0444);51MODULE_PARM_DESC(mono, "Mono capture mode (default is stereo)");52 53enum {54	PCI_ID_VX882HR,55	PCI_ID_PCX882HR,56	PCI_ID_VX881HR,57	PCI_ID_PCX881HR,58	PCI_ID_VX882E,59	PCI_ID_PCX882E,60	PCI_ID_VX881E,61	PCI_ID_PCX881E,62	PCI_ID_VX1222HR,63	PCI_ID_PCX1222HR,64	PCI_ID_VX1221HR,65	PCI_ID_PCX1221HR,66	PCI_ID_VX1222E,67	PCI_ID_PCX1222E,68	PCI_ID_VX1221E,69	PCI_ID_PCX1221E,70	PCI_ID_VX222HR,71	PCI_ID_VX222E,72	PCI_ID_PCX22HR,73	PCI_ID_PCX22E,74	PCI_ID_VX222HRMIC,75	PCI_ID_VX222E_MIC,76	PCI_ID_PCX924HR,77	PCI_ID_PCX924E,78	PCI_ID_PCX924HRMIC,79	PCI_ID_PCX924E_MIC,80	PCI_ID_VX442HR,81	PCI_ID_PCX442HR,82	PCI_ID_VX442E,83	PCI_ID_PCX442E,84	PCI_ID_VX822HR,85	PCI_ID_PCX822HR,86	PCI_ID_VX822E,87	PCI_ID_PCX822E,88	PCI_ID_LAST89};90 91static const struct pci_device_id pcxhr_ids[] = {92	{ 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },93	{ 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },94	{ 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },95	{ 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, },96	{ 0x10b5, 0x9056, 0x1369, 0xb021, 0, 0, PCI_ID_VX882E, },97	{ 0x10b5, 0x9056, 0x1369, 0xb121, 0, 0, PCI_ID_PCX882E, },98	{ 0x10b5, 0x9056, 0x1369, 0xb221, 0, 0, PCI_ID_VX881E, },99	{ 0x10b5, 0x9056, 0x1369, 0xb321, 0, 0, PCI_ID_PCX881E, },100	{ 0x10b5, 0x9656, 0x1369, 0xb401, 0, 0, PCI_ID_VX1222HR, },101	{ 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, },102	{ 0x10b5, 0x9656, 0x1369, 0xb601, 0, 0, PCI_ID_VX1221HR, },103	{ 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, },104	{ 0x10b5, 0x9056, 0x1369, 0xb421, 0, 0, PCI_ID_VX1222E, },105	{ 0x10b5, 0x9056, 0x1369, 0xb521, 0, 0, PCI_ID_PCX1222E, },106	{ 0x10b5, 0x9056, 0x1369, 0xb621, 0, 0, PCI_ID_VX1221E, },107	{ 0x10b5, 0x9056, 0x1369, 0xb721, 0, 0, PCI_ID_PCX1221E, },108	{ 0x10b5, 0x9056, 0x1369, 0xba01, 0, 0, PCI_ID_VX222HR, },109	{ 0x10b5, 0x9056, 0x1369, 0xba21, 0, 0, PCI_ID_VX222E, },110	{ 0x10b5, 0x9056, 0x1369, 0xbd01, 0, 0, PCI_ID_PCX22HR, },111	{ 0x10b5, 0x9056, 0x1369, 0xbd21, 0, 0, PCI_ID_PCX22E, },112	{ 0x10b5, 0x9056, 0x1369, 0xbc01, 0, 0, PCI_ID_VX222HRMIC, },113	{ 0x10b5, 0x9056, 0x1369, 0xbc21, 0, 0, PCI_ID_VX222E_MIC, },114	{ 0x10b5, 0x9056, 0x1369, 0xbb01, 0, 0, PCI_ID_PCX924HR, },115	{ 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },116	{ 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },117	{ 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },118	{ 0x10b5, 0x9656, 0x1369, 0xd001, 0, 0, PCI_ID_VX442HR, },119	{ 0x10b5, 0x9656, 0x1369, 0xd101, 0, 0, PCI_ID_PCX442HR, },120	{ 0x10b5, 0x9056, 0x1369, 0xd021, 0, 0, PCI_ID_VX442E, },121	{ 0x10b5, 0x9056, 0x1369, 0xd121, 0, 0, PCI_ID_PCX442E, },122	{ 0x10b5, 0x9656, 0x1369, 0xd201, 0, 0, PCI_ID_VX822HR, },123	{ 0x10b5, 0x9656, 0x1369, 0xd301, 0, 0, PCI_ID_PCX822HR, },124	{ 0x10b5, 0x9056, 0x1369, 0xd221, 0, 0, PCI_ID_VX822E, },125	{ 0x10b5, 0x9056, 0x1369, 0xd321, 0, 0, PCI_ID_PCX822E, },126	{ 0, }127};128 129MODULE_DEVICE_TABLE(pci, pcxhr_ids);130 131struct board_parameters {132	char* board_name;133	short playback_chips;134	short capture_chips;135	short fw_file_set;136	short firmware_num;137};138static const struct board_parameters pcxhr_board_params[] = {139[PCI_ID_VX882HR] =      { "VX882HR",      4, 4, 0, 41 },140[PCI_ID_PCX882HR] =     { "PCX882HR",     4, 4, 0, 41 },141[PCI_ID_VX881HR] =      { "VX881HR",      4, 4, 0, 41 },142[PCI_ID_PCX881HR] =     { "PCX881HR",     4, 4, 0, 41 },143[PCI_ID_VX882E] =       { "VX882e",       4, 4, 1, 41 },144[PCI_ID_PCX882E] =      { "PCX882e",      4, 4, 1, 41 },145[PCI_ID_VX881E] =       { "VX881e",       4, 4, 1, 41 },146[PCI_ID_PCX881E] =      { "PCX881e",      4, 4, 1, 41 },147[PCI_ID_VX1222HR] =     { "VX1222HR",     6, 1, 2, 42 },148[PCI_ID_PCX1222HR] =    { "PCX1222HR",    6, 1, 2, 42 },149[PCI_ID_VX1221HR] =     { "VX1221HR",     6, 1, 2, 42 },150[PCI_ID_PCX1221HR] =    { "PCX1221HR",    6, 1, 2, 42 },151[PCI_ID_VX1222E] =      { "VX1222e",      6, 1, 3, 42 },152[PCI_ID_PCX1222E] =     { "PCX1222e",     6, 1, 3, 42 },153[PCI_ID_VX1221E] =      { "VX1221e",      6, 1, 3, 42 },154[PCI_ID_PCX1221E] =     { "PCX1221e",     6, 1, 3, 42 },155[PCI_ID_VX222HR] =      { "VX222HR",      1, 1, 4, 44 },156[PCI_ID_VX222E] =       { "VX222e",       1, 1, 4, 44 },157[PCI_ID_PCX22HR] =      { "PCX22HR",      1, 0, 4, 44 },158[PCI_ID_PCX22E] =       { "PCX22e",       1, 0, 4, 44 },159[PCI_ID_VX222HRMIC] =   { "VX222HR-Mic",  1, 1, 5, 44 },160[PCI_ID_VX222E_MIC] =   { "VX222e-Mic",   1, 1, 5, 44 },161[PCI_ID_PCX924HR] =     { "PCX924HR",     1, 1, 5, 44 },162[PCI_ID_PCX924E] =      { "PCX924e",      1, 1, 5, 44 },163[PCI_ID_PCX924HRMIC] =  { "PCX924HR-Mic", 1, 1, 5, 44 },164[PCI_ID_PCX924E_MIC] =  { "PCX924e-Mic",  1, 1, 5, 44 },165[PCI_ID_VX442HR] =      { "VX442HR",      2, 2, 0, 41 },166[PCI_ID_PCX442HR] =     { "PCX442HR",     2, 2, 0, 41 },167[PCI_ID_VX442E] =       { "VX442e",       2, 2, 1, 41 },168[PCI_ID_PCX442E] =      { "PCX442e",      2, 2, 1, 41 },169[PCI_ID_VX822HR] =      { "VX822HR",      4, 1, 2, 42 },170[PCI_ID_PCX822HR] =     { "PCX822HR",     4, 1, 2, 42 },171[PCI_ID_VX822E] =       { "VX822e",       4, 1, 3, 42 },172[PCI_ID_PCX822E] =      { "PCX822e",      4, 1, 3, 42 },173};174 175/* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */176/* VX222HR, VX222e, PCX22HR and PCX22e */177#define PCXHR_BOARD_HAS_AES1(x) (x->fw_file_set != 4)178/* some boards do not support 192kHz on digital AES input plugs */179#define PCXHR_BOARD_AESIN_NO_192K(x) ((x->capture_chips == 0) || \180				      (x->fw_file_set == 0)   || \181				      (x->fw_file_set == 2))182 183static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,184				   unsigned int* realfreq)185{186	unsigned int reg;187 188	if (freq < 6900 || freq > 110000)189		return -EINVAL;190	reg = (28224000 * 2) / freq;191	reg = (reg - 1) / 2;192	if (reg < 0x200)193		*pllreg = reg + 0x800;194	else if (reg < 0x400)195		*pllreg = reg & 0x1ff;196	else if (reg < 0x800) {197		*pllreg = ((reg >> 1) & 0x1ff) + 0x200;198		reg &= ~1;199	} else {200		*pllreg = ((reg >> 2) & 0x1ff) + 0x400;201		reg &= ~3;202	}203	if (realfreq)204		*realfreq = (28224000 / (reg + 1));205	return 0;206}207 208 209#define PCXHR_FREQ_REG_MASK		0x1f210#define PCXHR_FREQ_QUARTZ_48000		0x00211#define PCXHR_FREQ_QUARTZ_24000		0x01212#define PCXHR_FREQ_QUARTZ_12000		0x09213#define PCXHR_FREQ_QUARTZ_32000		0x08214#define PCXHR_FREQ_QUARTZ_16000		0x04215#define PCXHR_FREQ_QUARTZ_8000		0x0c216#define PCXHR_FREQ_QUARTZ_44100		0x02217#define PCXHR_FREQ_QUARTZ_22050		0x0a218#define PCXHR_FREQ_QUARTZ_11025		0x06219#define PCXHR_FREQ_PLL			0x05220#define PCXHR_FREQ_QUARTZ_192000	0x10221#define PCXHR_FREQ_QUARTZ_96000		0x18222#define PCXHR_FREQ_QUARTZ_176400	0x14223#define PCXHR_FREQ_QUARTZ_88200		0x1c224#define PCXHR_FREQ_QUARTZ_128000	0x12225#define PCXHR_FREQ_QUARTZ_64000		0x1a226 227#define PCXHR_FREQ_WORD_CLOCK		0x0f228#define PCXHR_FREQ_SYNC_AES		0x0e229#define PCXHR_FREQ_AES_1		0x07230#define PCXHR_FREQ_AES_2		0x0b231#define PCXHR_FREQ_AES_3		0x03232#define PCXHR_FREQ_AES_4		0x0d233 234static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,235			       unsigned int *reg, unsigned int *freq)236{237	unsigned int val, realfreq, pllreg;238	struct pcxhr_rmh rmh;239	int err;240 241	realfreq = rate;242	switch (mgr->use_clock_type) {243	case PCXHR_CLOCK_TYPE_INTERNAL :	/* clock by quartz or pll */244		switch (rate) {245		case 48000 :	val = PCXHR_FREQ_QUARTZ_48000;	break;246		case 24000 :	val = PCXHR_FREQ_QUARTZ_24000;	break;247		case 12000 :	val = PCXHR_FREQ_QUARTZ_12000;	break;248		case 32000 :	val = PCXHR_FREQ_QUARTZ_32000;	break;249		case 16000 :	val = PCXHR_FREQ_QUARTZ_16000;	break;250		case 8000 :	val = PCXHR_FREQ_QUARTZ_8000;	break;251		case 44100 :	val = PCXHR_FREQ_QUARTZ_44100;	break;252		case 22050 :	val = PCXHR_FREQ_QUARTZ_22050;	break;253		case 11025 :	val = PCXHR_FREQ_QUARTZ_11025;	break;254		case 192000 :	val = PCXHR_FREQ_QUARTZ_192000;	break;255		case 96000 :	val = PCXHR_FREQ_QUARTZ_96000;	break;256		case 176400 :	val = PCXHR_FREQ_QUARTZ_176400;	break;257		case 88200 :	val = PCXHR_FREQ_QUARTZ_88200;	break;258		case 128000 :	val = PCXHR_FREQ_QUARTZ_128000;	break;259		case 64000 :	val = PCXHR_FREQ_QUARTZ_64000;	break;260		default :261			val = PCXHR_FREQ_PLL;262			/* get the value for the pll register */263			err = pcxhr_pll_freq_register(rate, &pllreg, &realfreq);264			if (err)265				return err;266			pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);267			rmh.cmd[0] |= IO_NUM_REG_GENCLK;268			rmh.cmd[1]  = pllreg & MASK_DSP_WORD;269			rmh.cmd[2]  = pllreg >> 24;270			rmh.cmd_len = 3;271			err = pcxhr_send_msg(mgr, &rmh);272			if (err < 0) {273				dev_err(&mgr->pci->dev,274					   "error CMD_ACCESS_IO_WRITE "275					   "for PLL register : %x!\n", err);276				return err;277			}278		}279		break;280	case PCXHR_CLOCK_TYPE_WORD_CLOCK:281		val = PCXHR_FREQ_WORD_CLOCK;282		break;283	case PCXHR_CLOCK_TYPE_AES_SYNC:284		val = PCXHR_FREQ_SYNC_AES;285		break;286	case PCXHR_CLOCK_TYPE_AES_1:287		val = PCXHR_FREQ_AES_1;288		break;289	case PCXHR_CLOCK_TYPE_AES_2:290		val = PCXHR_FREQ_AES_2;291		break;292	case PCXHR_CLOCK_TYPE_AES_3:293		val = PCXHR_FREQ_AES_3;294		break;295	case PCXHR_CLOCK_TYPE_AES_4:296		val = PCXHR_FREQ_AES_4;297		break;298	default:299		return -EINVAL;300	}301	*reg = val;302	*freq = realfreq;303	return 0;304}305 306 307static int pcxhr_sub_set_clock(struct pcxhr_mgr *mgr,308			       unsigned int rate,309			       int *changed)310{311	unsigned int val, realfreq, speed;312	struct pcxhr_rmh rmh;313	int err;314 315	err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq);316	if (err)317		return err;318 319	/* codec speed modes */320	if (rate < 55000)321		speed = 0;	/* single speed */322	else if (rate < 100000)323		speed = 1;	/* dual speed */324	else325		speed = 2;	/* quad speed */326	if (mgr->codec_speed != speed) {327		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */328		rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;329		if (DSP_EXT_CMD_SET(mgr)) {330			rmh.cmd[1]  = 1;331			rmh.cmd_len = 2;332		}333		err = pcxhr_send_msg(mgr, &rmh);334		if (err)335			return err;336 337		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */338		rmh.cmd[0] |= IO_NUM_SPEED_RATIO;339		rmh.cmd[1] = speed;340		rmh.cmd_len = 2;341		err = pcxhr_send_msg(mgr, &rmh);342		if (err)343			return err;344	}345	/* set the new frequency */346	dev_dbg(&mgr->pci->dev, "clock register : set %x\n", val);347	err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK,348					  val, changed);349	if (err)350		return err;351 352	mgr->sample_rate_real = realfreq;353	mgr->cur_clock_type = mgr->use_clock_type;354 355	/* unmute after codec speed modes */356	if (mgr->codec_speed != speed) {357		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */358		rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;359		if (DSP_EXT_CMD_SET(mgr)) {360			rmh.cmd[1]  = 1;361			rmh.cmd_len = 2;362		}363		err = pcxhr_send_msg(mgr, &rmh);364		if (err)365			return err;366		mgr->codec_speed = speed;	/* save new codec speed */367	}368 369	dev_dbg(&mgr->pci->dev, "%s to %dHz (realfreq=%d)\n", __func__,370		    rate, realfreq);371	return 0;372}373 374#define PCXHR_MODIFY_CLOCK_S_BIT	0x04375 376#define PCXHR_IRQ_TIMER_FREQ		92000377#define PCXHR_IRQ_TIMER_PERIOD		48378 379int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)380{381	struct pcxhr_rmh rmh;382	int err, changed;383 384	if (rate == 0)385		return 0; /* nothing to do */386 387	if (mgr->is_hr_stereo)388		err = hr222_sub_set_clock(mgr, rate, &changed);389	else390		err = pcxhr_sub_set_clock(mgr, rate, &changed);391 392	if (err)393		return err;394 395	if (changed) {396		pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK);397		rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos  */398		if (rate < PCXHR_IRQ_TIMER_FREQ)399			rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD;400		else401			rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD * 2;402		rmh.cmd[2] = rate;403		rmh.cmd_len = 3;404		err = pcxhr_send_msg(mgr, &rmh);405		if (err)406			return err;407	}408	return 0;409}410 411 412static int pcxhr_sub_get_external_clock(struct pcxhr_mgr *mgr,413					enum pcxhr_clock_type clock_type,414					int *sample_rate)415{416	struct pcxhr_rmh rmh;417	unsigned char reg;418	int err, rate;419 420	switch (clock_type) {421	case PCXHR_CLOCK_TYPE_WORD_CLOCK:422		reg = REG_STATUS_WORD_CLOCK;423		break;424	case PCXHR_CLOCK_TYPE_AES_SYNC:425		reg = REG_STATUS_AES_SYNC;426		break;427	case PCXHR_CLOCK_TYPE_AES_1:428		reg = REG_STATUS_AES_1;429		break;430	case PCXHR_CLOCK_TYPE_AES_2:431		reg = REG_STATUS_AES_2;432		break;433	case PCXHR_CLOCK_TYPE_AES_3:434		reg = REG_STATUS_AES_3;435		break;436	case PCXHR_CLOCK_TYPE_AES_4:437		reg = REG_STATUS_AES_4;438		break;439	default:440		return -EINVAL;441	}442	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);443	rmh.cmd_len = 2;444	rmh.cmd[0] |= IO_NUM_REG_STATUS;445	if (mgr->last_reg_stat != reg) {446		rmh.cmd[1]  = reg;447		err = pcxhr_send_msg(mgr, &rmh);448		if (err)449			return err;450		udelay(100);	/* wait minimum 2 sample_frames at 32kHz ! */451		mgr->last_reg_stat = reg;452	}453	rmh.cmd[1]  = REG_STATUS_CURRENT;454	err = pcxhr_send_msg(mgr, &rmh);455	if (err)456		return err;457	switch (rmh.stat[1] & 0x0f) {458	case REG_STATUS_SYNC_32000 :	rate = 32000; break;459	case REG_STATUS_SYNC_44100 :	rate = 44100; break;460	case REG_STATUS_SYNC_48000 :	rate = 48000; break;461	case REG_STATUS_SYNC_64000 :	rate = 64000; break;462	case REG_STATUS_SYNC_88200 :	rate = 88200; break;463	case REG_STATUS_SYNC_96000 :	rate = 96000; break;464	case REG_STATUS_SYNC_128000 :	rate = 128000; break;465	case REG_STATUS_SYNC_176400 :	rate = 176400; break;466	case REG_STATUS_SYNC_192000 :	rate = 192000; break;467	default: rate = 0;468	}469	dev_dbg(&mgr->pci->dev, "External clock is at %d Hz\n", rate);470	*sample_rate = rate;471	return 0;472}473 474 475int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,476			     enum pcxhr_clock_type clock_type,477			     int *sample_rate)478{479	if (mgr->is_hr_stereo)480		return hr222_get_external_clock(mgr, clock_type,481						sample_rate);482	else483		return pcxhr_sub_get_external_clock(mgr, clock_type,484						    sample_rate);485}486 487/*488 *  start or stop playback/capture substream489 */490static int pcxhr_set_stream_state(struct snd_pcxhr *chip,491				  struct pcxhr_stream *stream)492{493	int err;494	struct pcxhr_rmh rmh;495	int stream_mask, start;496 497	if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN)498		start = 1;499	else {500		if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) {501			dev_err(chip->card->dev,502				"%s CANNOT be stopped\n", __func__);503			return -EINVAL;504		}505		start = 0;506	}507	if (!stream->substream)508		return -EINVAL;509 510	stream->timer_abs_periods = 0;511	stream->timer_period_frag = 0;	/* reset theoretical stream pos */512	stream->timer_buf_periods = 0;513	stream->timer_is_synced = 0;514 515	stream_mask =516	  stream->pipe->is_capture ? 1 : 1<<stream->substream->number;517 518	pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM);519	pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,520				  stream->pipe->first_audio, 0, stream_mask);521 522	chip = snd_pcm_substream_chip(stream->substream);523 524	err = pcxhr_send_msg(chip->mgr, &rmh);525	if (err)526		dev_err(chip->card->dev,527			"ERROR %s err=%x;\n", __func__, err);528	stream->status =529	  start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED;530	return err;531}532 533#define HEADER_FMT_BASE_LIN		0xfed00000534#define HEADER_FMT_BASE_FLOAT		0xfad00000535#define HEADER_FMT_INTEL		0x00008000536#define HEADER_FMT_24BITS		0x00004000537#define HEADER_FMT_16BITS		0x00002000538#define HEADER_FMT_UPTO11		0x00000200539#define HEADER_FMT_UPTO32		0x00000100540#define HEADER_FMT_MONO			0x00000080541 542static int pcxhr_set_format(struct pcxhr_stream *stream)543{544	int err, is_capture, sample_rate, stream_num;545	struct snd_pcxhr *chip;546	struct pcxhr_rmh rmh;547	unsigned int header;548 549	chip = snd_pcm_substream_chip(stream->substream);550	switch (stream->format) {551	case SNDRV_PCM_FORMAT_U8:552		header = HEADER_FMT_BASE_LIN;553		break;554	case SNDRV_PCM_FORMAT_S16_LE:555		header = HEADER_FMT_BASE_LIN |556			 HEADER_FMT_16BITS | HEADER_FMT_INTEL;557		break;558	case SNDRV_PCM_FORMAT_S16_BE:559		header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS;560		break;561	case SNDRV_PCM_FORMAT_S24_3LE:562		header = HEADER_FMT_BASE_LIN |563			 HEADER_FMT_24BITS | HEADER_FMT_INTEL;564		break;565	case SNDRV_PCM_FORMAT_S24_3BE:566		header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS;567		break;568	case SNDRV_PCM_FORMAT_FLOAT_LE:569		header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL;570		break;571	default:572		dev_err(chip->card->dev,573			"error %s() : unknown format\n", __func__);574		return -EINVAL;575	}576 577	sample_rate = chip->mgr->sample_rate;578	if (sample_rate <= 32000 && sample_rate !=0) {579		if (sample_rate <= 11025)580			header |= HEADER_FMT_UPTO11;581		else582			header |= HEADER_FMT_UPTO32;583	}584	if (stream->channels == 1)585		header |= HEADER_FMT_MONO;586 587	is_capture = stream->pipe->is_capture;588	stream_num = is_capture ? 0 : stream->substream->number;589 590	pcxhr_init_rmh(&rmh, is_capture ?591		       CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);592	pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,593				  stream_num, 0);594	if (is_capture) {595		/* bug with old dsp versions: */596		/* bit 12 also sets the format of the playback stream */597		if (DSP_EXT_CMD_SET(chip->mgr))598			rmh.cmd[0] |= 1<<10;599		else600			rmh.cmd[0] |= 1<<12;601	}602	rmh.cmd[1] = 0;603	rmh.cmd_len = 2;604	if (DSP_EXT_CMD_SET(chip->mgr)) {605		/* add channels and set bit 19 if channels>2 */606		rmh.cmd[1] = stream->channels;607		if (!is_capture) {608			/* playback : add channel mask to command */609			rmh.cmd[2] = (stream->channels == 1) ? 0x01 : 0x03;610			rmh.cmd_len = 3;611		}612	}613	rmh.cmd[rmh.cmd_len++] = header >> 8;614	rmh.cmd[rmh.cmd_len++] = (header & 0xff) << 16;615	err = pcxhr_send_msg(chip->mgr, &rmh);616	if (err)617		dev_err(chip->card->dev,618			"ERROR %s err=%x;\n", __func__, err);619	return err;620}621 622static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)623{624	int err, is_capture, stream_num;625	struct pcxhr_rmh rmh;626	struct snd_pcm_substream *subs = stream->substream;627	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);628 629	is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);630	stream_num = is_capture ? 0 : subs->number;631 632	dev_dbg(chip->card->dev,633		"%s(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", __func__,634		is_capture ? 'c' : 'p',635		chip->chip_idx, (void *)(long)subs->runtime->dma_addr,636		subs->runtime->dma_bytes, subs->number);637 638	pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);639	pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,640				  stream_num, 0);641 642	/* max buffer size is 2 MByte */643	snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);644	/* size in bits */645	rmh.cmd[1] = subs->runtime->dma_bytes * 8;646	/* most significant byte */647	rmh.cmd[2] = subs->runtime->dma_addr >> 24;648	/* this is a circular buffer */649	rmh.cmd[2] |= 1<<19;650	/* least 3 significant bytes */651	rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD;652	rmh.cmd_len = 4;653	err = pcxhr_send_msg(chip->mgr, &rmh);654	if (err)655		dev_err(chip->card->dev,656			   "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err);657	return err;658}659 660 661#if 0662static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream,663				   snd_pcm_uframes_t *sample_count)664{665	struct pcxhr_rmh rmh;666	int err;667	pcxhr_t *chip = snd_pcm_substream_chip(stream->substream);668	pcxhr_init_rmh(&rmh, CMD_PIPE_SAMPLE_COUNT);669	pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 0, 0,670				  1<<stream->pipe->first_audio);671	err = pcxhr_send_msg(chip->mgr, &rmh);672	if (err == 0) {673		*sample_count = ((snd_pcm_uframes_t)rmh.stat[0]) << 24;674		*sample_count += (snd_pcm_uframes_t)rmh.stat[1];675	}676	dev_dbg(chip->card->dev, "PIPE_SAMPLE_COUNT = %lx\n", *sample_count);677	return err;678}679#endif680 681static inline int pcxhr_stream_scheduled_get_pipe(struct pcxhr_stream *stream,682						  struct pcxhr_pipe **pipe)683{684	if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN) {685		*pipe = stream->pipe;686		return 1;687	}688	return 0;689}690 691static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)692{693	int i, j, err;694	struct pcxhr_pipe *pipe;695	struct snd_pcxhr *chip;696	int capture_mask = 0;697	int playback_mask = 0;698 699#ifdef CONFIG_SND_DEBUG_VERBOSE700	ktime_t start_time, stop_time, diff_time;701 702	start_time = ktime_get();703#endif704	mutex_lock(&mgr->setup_mutex);705 706	/* check the pipes concerned and build pipe_array */707	for (i = 0; i < mgr->num_cards; i++) {708		chip = mgr->chip[i];709		for (j = 0; j < chip->nb_streams_capt; j++) {710			if (pcxhr_stream_scheduled_get_pipe(&chip->capture_stream[j], &pipe))711				capture_mask |= (1 << pipe->first_audio);712		}713		for (j = 0; j < chip->nb_streams_play; j++) {714			if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) {715				playback_mask |= (1 << pipe->first_audio);716				break;	/* add only once, as all playback717					 * streams of one chip use the same pipe718					 */719			}720		}721	}722	if (capture_mask == 0 && playback_mask == 0) {723		mutex_unlock(&mgr->setup_mutex);724		dev_err(&mgr->pci->dev, "%s : no pipes\n", __func__);725		return;726	}727 728	dev_dbg(&mgr->pci->dev, "%s : playback_mask=%x capture_mask=%x\n",729		    __func__, playback_mask, capture_mask);730 731	/* synchronous stop of all the pipes concerned */732	err = pcxhr_set_pipe_state(mgr,  playback_mask, capture_mask, 0);733	if (err) {734		mutex_unlock(&mgr->setup_mutex);735		dev_err(&mgr->pci->dev, "%s : "736			   "error stop pipes (P%x C%x)\n",737			   __func__, playback_mask, capture_mask);738		return;739	}740 741	/* the dsp lost format and buffer info with the stop pipe */742	for (i = 0; i < mgr->num_cards; i++) {743		struct pcxhr_stream *stream;744		chip = mgr->chip[i];745		for (j = 0; j < chip->nb_streams_capt; j++) {746			stream = &chip->capture_stream[j];747			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {748				err = pcxhr_set_format(stream);749				err = pcxhr_update_r_buffer(stream);750			}751		}752		for (j = 0; j < chip->nb_streams_play; j++) {753			stream = &chip->playback_stream[j];754			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {755				err = pcxhr_set_format(stream);756				err = pcxhr_update_r_buffer(stream);757			}758		}759	}760	/* start all the streams */761	for (i = 0; i < mgr->num_cards; i++) {762		struct pcxhr_stream *stream;763		chip = mgr->chip[i];764		for (j = 0; j < chip->nb_streams_capt; j++) {765			stream = &chip->capture_stream[j];766			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))767				err = pcxhr_set_stream_state(chip, stream);768		}769		for (j = 0; j < chip->nb_streams_play; j++) {770			stream = &chip->playback_stream[j];771			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))772				err = pcxhr_set_stream_state(chip, stream);773		}774	}775 776	/* synchronous start of all the pipes concerned */777	err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);778	if (err) {779		mutex_unlock(&mgr->setup_mutex);780		dev_err(&mgr->pci->dev, "%s : "781			   "error start pipes (P%x C%x)\n",782			   __func__, playback_mask, capture_mask);783		return;784	}785 786	/* put the streams into the running state now787	 * (increment pointer by interrupt)788	 */789	mutex_lock(&mgr->lock);790	for ( i =0; i < mgr->num_cards; i++) {791		struct pcxhr_stream *stream;792		chip = mgr->chip[i];793		for(j = 0; j < chip->nb_streams_capt; j++) {794			stream = &chip->capture_stream[j];795			if(stream->status == PCXHR_STREAM_STATUS_STARTED)796				stream->status = PCXHR_STREAM_STATUS_RUNNING;797		}798		for (j = 0; j < chip->nb_streams_play; j++) {799			stream = &chip->playback_stream[j];800			if (stream->status == PCXHR_STREAM_STATUS_STARTED) {801				/* playback will already have advanced ! */802				stream->timer_period_frag += mgr->granularity;803				stream->status = PCXHR_STREAM_STATUS_RUNNING;804			}805		}806	}807	mutex_unlock(&mgr->lock);808 809	mutex_unlock(&mgr->setup_mutex);810 811#ifdef CONFIG_SND_DEBUG_VERBOSE812	stop_time = ktime_get();813	diff_time = ktime_sub(stop_time, start_time);814	dev_dbg(&mgr->pci->dev, "***TRIGGER START*** TIME = %ld (err = %x)\n",815		    (long)(ktime_to_ns(diff_time)), err);816#endif817}818 819 820/*821 *  trigger callback822 */823static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)824{825	struct pcxhr_stream *stream;826	struct snd_pcm_substream *s;827	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);828 829	switch (cmd) {830	case SNDRV_PCM_TRIGGER_START:831		dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_START\n");832		if (snd_pcm_stream_linked(subs)) {833			snd_pcm_group_for_each_entry(s, subs) {834				if (snd_pcm_substream_chip(s) != chip)835					continue;836				stream = s->runtime->private_data;837				stream->status =838					PCXHR_STREAM_STATUS_SCHEDULE_RUN;839				snd_pcm_trigger_done(s, subs);840			}841			pcxhr_start_linked_stream(chip->mgr);842		} else {843			stream = subs->runtime->private_data;844			dev_dbg(chip->card->dev, "Only one Substream %c %d\n",845				    stream->pipe->is_capture ? 'C' : 'P',846				    stream->pipe->first_audio);847			if (pcxhr_set_format(stream))848				return -EINVAL;849			if (pcxhr_update_r_buffer(stream))850				return -EINVAL;851 852			stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN;853			if (pcxhr_set_stream_state(chip, stream))854				return -EINVAL;855			stream->status = PCXHR_STREAM_STATUS_RUNNING;856		}857		break;858	case SNDRV_PCM_TRIGGER_STOP:859		dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_STOP\n");860		snd_pcm_group_for_each_entry(s, subs) {861			stream = s->runtime->private_data;862			stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP;863			if (pcxhr_set_stream_state(chip, stream))864				return -EINVAL;865			snd_pcm_trigger_done(s, subs);866		}867		break;868	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:869	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:870		/* TODO */871	default:872		return -EINVAL;873	}874	return 0;875}876 877 878static int pcxhr_hardware_timer(struct pcxhr_mgr *mgr, int start)879{880	struct pcxhr_rmh rmh;881	int err;882 883	pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT);884	if (start) {885		/* last dsp time invalid */886		mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;887		rmh.cmd[0] |= mgr->granularity;888	}889	err = pcxhr_send_msg(mgr, &rmh);890	if (err < 0)891		dev_err(&mgr->pci->dev, "error %s err(%x)\n", __func__,892			   err);893	return err;894}895 896/*897 *  prepare callback for all pcms898 */899static int pcxhr_prepare(struct snd_pcm_substream *subs)900{901	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);902	struct pcxhr_mgr *mgr = chip->mgr;903	int err = 0;904 905	dev_dbg(chip->card->dev,906		"%s : period_size(%lx) periods(%x) buffer_size(%lx)\n", __func__,907		    subs->runtime->period_size, subs->runtime->periods,908		    subs->runtime->buffer_size);909 910	mutex_lock(&mgr->setup_mutex);911 912	do {913		/* only the first stream can choose the sample rate */914		/* set the clock only once (first stream) */915		if (mgr->sample_rate != subs->runtime->rate) {916			err = pcxhr_set_clock(mgr, subs->runtime->rate);917			if (err)918				break;919			if (mgr->sample_rate == 0)920				/* start the DSP-timer */921				err = pcxhr_hardware_timer(mgr, 1);922			mgr->sample_rate = subs->runtime->rate;923		}924	} while(0);	/* do only once (so we can use break instead of goto) */925 926	mutex_unlock(&mgr->setup_mutex);927 928	return err;929}930 931 932/*933 *  HW_PARAMS callback for all pcms934 */935static int pcxhr_hw_params(struct snd_pcm_substream *subs,936			   struct snd_pcm_hw_params *hw)937{938	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);939	struct pcxhr_mgr *mgr = chip->mgr;940	struct pcxhr_stream *stream = subs->runtime->private_data;941 942	mutex_lock(&mgr->setup_mutex);943 944	/* set up channels */945	stream->channels = params_channels(hw);946	/* set up format for the stream */947	stream->format = params_format(hw);948 949	mutex_unlock(&mgr->setup_mutex);950 951	return 0;952}953 954 955/*956 *  CONFIGURATION SPACE for all pcms, mono pcm must update channels_max957 */958static const struct snd_pcm_hardware pcxhr_caps =959{960	.info             = (SNDRV_PCM_INFO_MMAP |961			     SNDRV_PCM_INFO_INTERLEAVED |962			     SNDRV_PCM_INFO_MMAP_VALID |963			     SNDRV_PCM_INFO_SYNC_START),964	.formats	  = (SNDRV_PCM_FMTBIT_U8 |965			     SNDRV_PCM_FMTBIT_S16_LE |966			     SNDRV_PCM_FMTBIT_S16_BE |967			     SNDRV_PCM_FMTBIT_S24_3LE |968			     SNDRV_PCM_FMTBIT_S24_3BE |969			     SNDRV_PCM_FMTBIT_FLOAT_LE),970	.rates            = (SNDRV_PCM_RATE_CONTINUOUS |971			     SNDRV_PCM_RATE_8000_192000),972	.rate_min         = 8000,973	.rate_max         = 192000,974	.channels_min     = 1,975	.channels_max     = 2,976	.buffer_bytes_max = (32*1024),977	/* 1 byte == 1 frame U8 mono (PCXHR_GRANULARITY is frames!) */978	.period_bytes_min = (2*PCXHR_GRANULARITY),979	.period_bytes_max = (16*1024),980	.periods_min      = 2,981	.periods_max      = (32*1024/PCXHR_GRANULARITY),982};983 984 985static int pcxhr_open(struct snd_pcm_substream *subs)986{987	struct snd_pcxhr       *chip = snd_pcm_substream_chip(subs);988	struct pcxhr_mgr       *mgr = chip->mgr;989	struct snd_pcm_runtime *runtime = subs->runtime;990	struct pcxhr_stream    *stream;991	int err;992 993	mutex_lock(&mgr->setup_mutex);994 995	/* copy the struct snd_pcm_hardware struct */996	runtime->hw = pcxhr_caps;997 998	if( subs->stream == SNDRV_PCM_STREAM_PLAYBACK ) {999		dev_dbg(chip->card->dev, "%s playback chip%d subs%d\n",1000			    __func__, chip->chip_idx, subs->number);1001		stream = &chip->playback_stream[subs->number];1002	} else {1003		dev_dbg(chip->card->dev, "%s capture chip%d subs%d\n",1004			    __func__, chip->chip_idx, subs->number);1005		if (mgr->mono_capture)1006			runtime->hw.channels_max = 1;1007		else1008			runtime->hw.channels_min = 2;1009		stream = &chip->capture_stream[subs->number];1010	}1011	if (stream->status != PCXHR_STREAM_STATUS_FREE){1012		/* streams in use */1013		dev_err(chip->card->dev, "%s chip%d subs%d in use\n",1014			   __func__, chip->chip_idx, subs->number);1015		mutex_unlock(&mgr->setup_mutex);1016		return -EBUSY;1017	}1018 1019	/* float format support is in some cases buggy on stereo cards */1020	if (mgr->is_hr_stereo)1021		runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_FLOAT_LE;1022 1023	/* buffer-size should better be multiple of period-size */1024	err = snd_pcm_hw_constraint_integer(runtime,1025					    SNDRV_PCM_HW_PARAM_PERIODS);1026	if (err < 0) {1027		mutex_unlock(&mgr->setup_mutex);1028		return err;1029	}1030 1031	/* if a sample rate is already used or fixed by external clock,1032	 * the stream cannot change1033	 */1034	if (mgr->sample_rate)1035		runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;1036	else {1037		if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {1038			int external_rate;1039			if (pcxhr_get_external_clock(mgr, mgr->use_clock_type,1040						     &external_rate) ||1041			    external_rate == 0) {1042				/* cannot detect the external clock rate */1043				mutex_unlock(&mgr->setup_mutex);1044				return -EBUSY;1045			}1046			runtime->hw.rate_min = external_rate;1047			runtime->hw.rate_max = external_rate;1048		}1049	}1050 1051	stream->status      = PCXHR_STREAM_STATUS_OPEN;1052	stream->substream   = subs;1053	stream->channels    = 0; /* not configured yet */1054 1055	runtime->private_data = stream;1056 1057	/* better get a divisor of granularity values (96 or 192) */1058	snd_pcm_hw_constraint_step(runtime, 0,1059				   SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);1060	snd_pcm_hw_constraint_step(runtime, 0,1061				   SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32);1062	snd_pcm_set_sync(subs);1063 1064	mgr->ref_count_rate++;1065 1066	mutex_unlock(&mgr->setup_mutex);1067	return 0;1068}1069 1070 1071static int pcxhr_close(struct snd_pcm_substream *subs)1072{1073	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);1074	struct pcxhr_mgr *mgr = chip->mgr;1075	struct pcxhr_stream *stream = subs->runtime->private_data;1076 1077	mutex_lock(&mgr->setup_mutex);1078 1079	dev_dbg(chip->card->dev, "%s chip%d subs%d\n", __func__,1080		    chip->chip_idx, subs->number);1081 1082	/* sample rate released */1083	if (--mgr->ref_count_rate == 0) {1084		mgr->sample_rate = 0;	/* the sample rate is no more locked */1085		pcxhr_hardware_timer(mgr, 0);	/* stop the DSP-timer */1086	}1087 1088	stream->status    = PCXHR_STREAM_STATUS_FREE;1089	stream->substream = NULL;1090 1091	mutex_unlock(&mgr->setup_mutex);1092 1093	return 0;1094}1095 1096 1097static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs)1098{1099	u_int32_t timer_period_frag;1100	int timer_buf_periods;1101	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);1102	struct snd_pcm_runtime *runtime = subs->runtime;1103	struct pcxhr_stream *stream  = runtime->private_data;1104 1105	mutex_lock(&chip->mgr->lock);1106 1107	/* get the period fragment and the nb of periods in the buffer */1108	timer_period_frag = stream->timer_period_frag;1109	timer_buf_periods = stream->timer_buf_periods;1110 1111	mutex_unlock(&chip->mgr->lock);1112 1113	return (snd_pcm_uframes_t)((timer_buf_periods * runtime->period_size) +1114				   timer_period_frag);1115}1116 1117 1118static const struct snd_pcm_ops pcxhr_ops = {1119	.open      = pcxhr_open,1120	.close     = pcxhr_close,1121	.prepare   = pcxhr_prepare,1122	.hw_params = pcxhr_hw_params,1123	.trigger   = pcxhr_trigger,1124	.pointer   = pcxhr_stream_pointer,1125};1126 1127/*1128 */1129int pcxhr_create_pcm(struct snd_pcxhr *chip)1130{1131	int err;1132	struct snd_pcm *pcm;1133	char name[32];1134 1135	snprintf(name, sizeof(name), "pcxhr %d", chip->chip_idx);1136	err = snd_pcm_new(chip->card, name, 0,1137			  chip->nb_streams_play,1138			  chip->nb_streams_capt, &pcm);1139	if (err < 0) {1140		dev_err(chip->card->dev, "cannot create pcm %s\n", name);1141		return err;1142	}1143	pcm->private_data = chip;1144 1145	if (chip->nb_streams_play)1146		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcxhr_ops);1147	if (chip->nb_streams_capt)1148		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcxhr_ops);1149 1150	pcm->info_flags = 0;1151	pcm->nonatomic = true;1152	strcpy(pcm->name, name);1153 1154	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,1155				       &chip->mgr->pci->dev,1156				       32*1024, 32*1024);1157	chip->pcm = pcm;1158	return 0;1159}1160 1161static int pcxhr_chip_free(struct snd_pcxhr *chip)1162{1163	kfree(chip);1164	return 0;1165}1166 1167static int pcxhr_chip_dev_free(struct snd_device *device)1168{1169	struct snd_pcxhr *chip = device->device_data;1170	return pcxhr_chip_free(chip);1171}1172 1173 1174/*1175 */1176static int pcxhr_create(struct pcxhr_mgr *mgr,1177			struct snd_card *card, int idx)1178{1179	int err;1180	struct snd_pcxhr *chip;1181	static const struct snd_device_ops ops = {1182		.dev_free = pcxhr_chip_dev_free,1183	};1184 1185	chip = kzalloc(sizeof(*chip), GFP_KERNEL);1186	if (!chip)1187		return -ENOMEM;1188 1189	chip->card = card;1190	chip->chip_idx = idx;1191	chip->mgr = mgr;1192	card->sync_irq = mgr->irq;1193 1194	if (idx < mgr->playback_chips)1195		/* stereo or mono streams */1196		chip->nb_streams_play = PCXHR_PLAYBACK_STREAMS;1197 1198	if (idx < mgr->capture_chips) {1199		if (mgr->mono_capture)1200			chip->nb_streams_capt = 2;	/* 2 mono streams */1201		else1202			chip->nb_streams_capt = 1;	/* or 1 stereo stream */1203	}1204 1205	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);1206	if (err < 0) {1207		pcxhr_chip_free(chip);1208		return err;1209	}1210 1211	mgr->chip[idx] = chip;1212 1213	return 0;1214}1215 1216/* proc interface */1217static void pcxhr_proc_info(struct snd_info_entry *entry,1218			    struct snd_info_buffer *buffer)1219{1220	struct snd_pcxhr *chip = entry->private_data;1221	struct pcxhr_mgr *mgr = chip->mgr;1222 1223	snd_iprintf(buffer, "\n%s\n", mgr->name);1224 1225	/* stats available when embedded DSP is running */1226	if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {1227		struct pcxhr_rmh rmh;1228		short ver_maj = (mgr->dsp_version >> 16) & 0xff;1229		short ver_min = (mgr->dsp_version >> 8) & 0xff;1230		short ver_build = mgr->dsp_version & 0xff;1231		snd_iprintf(buffer, "module version %s\n",1232			    PCXHR_DRIVER_VERSION_STRING);1233		snd_iprintf(buffer, "dsp version %d.%d.%d\n",1234			    ver_maj, ver_min, ver_build);1235		if (mgr->board_has_analog)1236			snd_iprintf(buffer, "analog io available\n");1237		else1238			snd_iprintf(buffer, "digital only board\n");1239 1240		/* calc cpu load of the dsp */1241		pcxhr_init_rmh(&rmh, CMD_GET_DSP_RESOURCES);1242		if( ! pcxhr_send_msg(mgr, &rmh) ) {1243			int cur = rmh.stat[0];1244			int ref = rmh.stat[1];1245			if (ref > 0) {1246				if (mgr->sample_rate_real != 0 &&1247				    mgr->sample_rate_real != 48000) {1248					ref = (ref * 48000) /1249					  mgr->sample_rate_real;1250					if (mgr->sample_rate_real >=1251					    PCXHR_IRQ_TIMER_FREQ)1252						ref *= 2;1253				}1254				cur = 100 - (100 * cur) / ref;1255				snd_iprintf(buffer, "cpu load    %d%%\n", cur);1256				snd_iprintf(buffer, "buffer pool %d/%d\n",1257					    rmh.stat[2], rmh.stat[3]);1258			}1259		}1260		snd_iprintf(buffer, "dma granularity : %d\n",1261			    mgr->granularity);1262		snd_iprintf(buffer, "dsp time errors : %d\n",1263			    mgr->dsp_time_err);1264		snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n",1265			    mgr->async_err_pipe_xrun);1266		snd_iprintf(buffer, "dsp async stream xrun errors : %d\n",1267			    mgr->async_err_stream_xrun);1268		snd_iprintf(buffer, "dsp async last other error : %x\n",1269			    mgr->async_err_other_last);1270		/* debug zone dsp */1271		rmh.cmd[0] = 0x4200 + PCXHR_SIZE_MAX_STATUS;1272		rmh.cmd_len = 1;1273		rmh.stat_len = PCXHR_SIZE_MAX_STATUS;1274		rmh.dsp_stat = 0;1275		rmh.cmd_idx = CMD_LAST_INDEX;1276		if( ! pcxhr_send_msg(mgr, &rmh) ) {1277			int i;1278			if (rmh.stat_len > 8)1279				rmh.stat_len = 8;1280			for (i = 0; i < rmh.stat_len; i++)1281				snd_iprintf(buffer, "debug[%02d] = %06x\n",1282					    i,  rmh.stat[i]);1283		}1284	} else1285		snd_iprintf(buffer, "no firmware loaded\n");1286	snd_iprintf(buffer, "\n");1287}1288static void pcxhr_proc_sync(struct snd_info_entry *entry,1289			    struct snd_info_buffer *buffer)1290{1291	struct snd_pcxhr *chip = entry->private_data;1292	struct pcxhr_mgr *mgr = chip->mgr;1293	static const char *textsHR22[3] = {1294		"Internal", "AES Sync", "AES 1"1295	};1296	static const char *textsPCXHR[7] = {1297		"Internal", "Word", "AES Sync",1298		"AES 1", "AES 2", "AES 3", "AES 4"1299	};1300	const char **texts;1301	int max_clock;1302	if (mgr->is_hr_stereo) {1303		texts = textsHR22;1304		max_clock = HR22_CLOCK_TYPE_MAX;1305	} else {1306		texts = textsPCXHR;1307		max_clock = PCXHR_CLOCK_TYPE_MAX;1308	}1309 1310	snd_iprintf(buffer, "\n%s\n", mgr->name);1311	snd_iprintf(buffer, "Current Sample Clock\t: %s\n",1312		    texts[mgr->cur_clock_type]);1313	snd_iprintf(buffer, "Current Sample Rate\t= %d\n",1314		    mgr->sample_rate_real);1315	/* commands available when embedded DSP is running */1316	if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {1317		int i, err, sample_rate;1318		for (i = 1; i <= max_clock; i++) {1319			err = pcxhr_get_external_clock(mgr, i, &sample_rate);1320			if (err)1321				break;1322			snd_iprintf(buffer, "%s Clock\t\t= %d\n",1323				    texts[i], sample_rate);1324		}1325	} else1326		snd_iprintf(buffer, "no firmware loaded\n");1327	snd_iprintf(buffer, "\n");1328}1329 1330static void pcxhr_proc_gpio_read(struct snd_info_entry *entry,1331				 struct snd_info_buffer *buffer)1332{1333	struct snd_pcxhr *chip = entry->private_data;1334	struct pcxhr_mgr *mgr = chip->mgr;1335	/* commands available when embedded DSP is running */1336	if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {1337		/* gpio ports on stereo boards only available */1338		int value = 0;1339		hr222_read_gpio(mgr, 1, &value);	/* GPI */1340		snd_iprintf(buffer, "GPI: 0x%x\n", value);1341		hr222_read_gpio(mgr, 0, &value);	/* GP0 */1342		snd_iprintf(buffer, "GPO: 0x%x\n", value);1343	} else1344		snd_iprintf(buffer, "no firmware loaded\n");1345	snd_iprintf(buffer, "\n");1346}1347static void pcxhr_proc_gpo_write(struct snd_info_entry *entry,1348				 struct snd_info_buffer *buffer)1349{1350	struct snd_pcxhr *chip = entry->private_data;1351	struct pcxhr_mgr *mgr = chip->mgr;1352	char line[64];1353	int value;1354	/* commands available when embedded DSP is running */1355	if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)))1356		return;1357	while (!snd_info_get_line(buffer, line, sizeof(line))) {1358		if (sscanf(line, "GPO: 0x%x", &value) != 1)1359			continue;1360		hr222_write_gpo(mgr, value);	/* GP0 */1361	}1362}1363 1364/* Access to the results of the CMD_GET_TIME_CODE RMH */1365#define TIME_CODE_VALID_MASK	0x008000001366#define TIME_CODE_NEW_MASK	0x004000001367#define TIME_CODE_BACK_MASK	0x002000001368#define TIME_CODE_WAIT_MASK	0x001000001369 1370/* Values for the CMD_MANAGE_SIGNAL RMH */1371#define MANAGE_SIGNAL_TIME_CODE	0x011372#define MANAGE_SIGNAL_MIDI	0x021373 1374/* linear time code read proc*/1375static void pcxhr_proc_ltc(struct snd_info_entry *entry,1376			   struct snd_info_buffer *buffer)1377{1378	struct snd_pcxhr *chip = entry->private_data;1379	struct pcxhr_mgr *mgr = chip->mgr;1380	struct pcxhr_rmh rmh;1381	unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm;1382	int err;1383	/* commands available when embedded DSP is running */1384	if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) {1385		snd_iprintf(buffer, "no firmware loaded\n");1386		return;1387	}1388	if (!mgr->capture_ltc) {1389		pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL);1390		rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE;1391		err = pcxhr_send_msg(mgr, &rmh);1392		if (err) {1393			snd_iprintf(buffer, "ltc not activated (%d)\n", err);1394			return;1395		}1396		if (mgr->is_hr_stereo)1397			hr222_manage_timecode(mgr, 1);1398		else1399			pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE,1400						    REG_CONT_VALSMPTE, NULL);1401		mgr->capture_ltc = 1;1402	}1403	pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE);1404	err = pcxhr_send_msg(mgr, &rmh);1405	if (err) {1406		snd_iprintf(buffer, "ltc read error (err=%d)\n", err);1407		return ;1408	}1409	ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf);1410	ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf);1411	ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf);1412	ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf);1413 1414	snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n",1415			    ltcHrs, ltcMin, ltcSec, ltcFrm);1416	snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff,1417			    rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff);1418	/*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n",1419			    rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/1420	if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) {1421		snd_iprintf(buffer, "warning: linear timecode not valid\n");1422	}1423}1424 1425static void pcxhr_proc_init(struct snd_pcxhr *chip)1426{1427	snd_card_ro_proc_new(chip->card, "info", chip, pcxhr_proc_info);1428	snd_card_ro_proc_new(chip->card, "sync", chip, pcxhr_proc_sync);1429	/* gpio available on stereo sound cards only */1430	if (chip->mgr->is_hr_stereo)1431		snd_card_rw_proc_new(chip->card, "gpio", chip,1432				     pcxhr_proc_gpio_read,1433				     pcxhr_proc_gpo_write);1434	snd_card_ro_proc_new(chip->card, "ltc", chip, pcxhr_proc_ltc);1435}1436/* end of proc interface */1437 1438/*1439 * release all the cards assigned to a manager instance1440 */1441static int pcxhr_free(struct pcxhr_mgr *mgr)1442{1443	unsigned int i;1444 1445	for (i = 0; i < mgr->num_cards; i++) {1446		if (mgr->chip[i])1447			snd_card_free(mgr->chip[i]->card);1448	}1449 1450	/* reset board if some firmware was loaded */1451	if(mgr->dsp_loaded) {1452		pcxhr_reset_board(mgr);1453		dev_dbg(&mgr->pci->dev, "reset pcxhr !\n");1454	}1455 1456	/* release irq  */1457	if (mgr->irq >= 0)1458		free_irq(mgr->irq, mgr);1459 1460	pci_release_regions(mgr->pci);1461 1462	/* free hostport purgebuffer */1463	if (mgr->hostport.area) {1464		snd_dma_free_pages(&mgr->hostport);1465		mgr->hostport.area = NULL;1466	}1467 1468	kfree(mgr->prmh);1469 1470	pci_disable_device(mgr->pci);1471	kfree(mgr);1472	return 0;1473}1474 1475/*1476 *    probe function - creates the card manager1477 */1478static int pcxhr_probe(struct pci_dev *pci,1479		       const struct pci_device_id *pci_id)1480{1481	static int dev;1482	struct pcxhr_mgr *mgr;1483	unsigned int i;1484	int err;1485	size_t size;1486	char *card_name;1487 1488	if (dev >= SNDRV_CARDS)1489		return -ENODEV;1490	if (! enable[dev]) {1491		dev++;1492		return -ENOENT;1493	}1494 1495	/* enable PCI device */1496	err = pci_enable_device(pci);1497	if (err < 0)1498		return err;1499	pci_set_master(pci);1500 1501	/* check if we can restrict PCI DMA transfers to 32 bits */1502	if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) {1503		dev_err(&pci->dev,1504			"architecture does not support 32bit PCI busmaster DMA\n");1505		pci_disable_device(pci);1506		return -ENXIO;1507	}1508 1509	/* alloc card manager */1510	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);1511	if (! mgr) {1512		pci_disable_device(pci);1513		return -ENOMEM;1514	}1515 1516	if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) {1517		kfree(mgr);1518		pci_disable_device(pci);1519		return -ENODEV;1520	}1521	card_name =1522		pcxhr_board_params[pci_id->driver_data].board_name;1523	mgr->playback_chips =1524		pcxhr_board_params[pci_id->driver_data].playback_chips;1525	mgr->capture_chips  =1526		pcxhr_board_params[pci_id->driver_data].capture_chips;1527	mgr->fw_file_set =1528		pcxhr_board_params[pci_id->driver_data].fw_file_set;1529	mgr->firmware_num  =1530		pcxhr_board_params[pci_id->driver_data].firmware_num;1531	mgr->mono_capture = mono[dev];1532	mgr->is_hr_stereo = (mgr->playback_chips == 1);1533	mgr->board_has_aes1 = PCXHR_BOARD_HAS_AES1(mgr);1534	mgr->board_aes_in_192k = !PCXHR_BOARD_AESIN_NO_192K(mgr);1535 1536	if (mgr->is_hr_stereo)1537		mgr->granularity = PCXHR_GRANULARITY_HR22;1538	else1539		mgr->granularity = PCXHR_GRANULARITY;1540 1541	/* resource assignment */1542	err = pci_request_regions(pci, card_name);1543	if (err < 0) {1544		kfree(mgr);1545		pci_disable_device(pci);1546		return err;1547	}1548	for (i = 0; i < 3; i++)1549		mgr->port[i] = pci_resource_start(pci, i);1550 1551	mgr->pci = pci;1552	mgr->irq = -1;1553 1554	if (request_threaded_irq(pci->irq, pcxhr_interrupt,1555				 pcxhr_threaded_irq, IRQF_SHARED,1556				 KBUILD_MODNAME, mgr)) {1557		dev_err(&pci->dev, "unable to grab IRQ %d\n", pci->irq);1558		pcxhr_free(mgr);1559		return -EBUSY;1560	}1561	mgr->irq = pci->irq;1562 1563	snprintf(mgr->name, sizeof(mgr->name),1564		 "Digigram at 0x%lx & 0x%lx, 0x%lx irq %i",1565		 mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);1566 1567	/* ISR lock  */1568	mutex_init(&mgr->lock);1569	mutex_init(&mgr->msg_lock);1570 1571	/* init setup mutex*/1572	mutex_init(&mgr->setup_mutex);1573 1574	mgr->prmh = kmalloc(sizeof(*mgr->prmh) +1575			    sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS -1576					   PCXHR_SIZE_MAX_STATUS),1577			    GFP_KERNEL);1578	if (! mgr->prmh) {1579		pcxhr_free(mgr);1580		return -ENOMEM;1581	}1582 1583	for (i=0; i < PCXHR_MAX_CARDS; i++) {1584		struct snd_card *card;1585		char tmpid[16];1586		int idx;1587 1588		if (i >= max(mgr->playback_chips, mgr->capture_chips))1589			break;1590		mgr->num_cards++;1591 1592		if (index[dev] < 0)1593			idx = index[dev];1594		else1595			idx = index[dev] + i;1596 1597		snprintf(tmpid, sizeof(tmpid), "%s-%d",1598			 id[dev] ? id[dev] : card_name, i);1599		err = snd_card_new(&pci->dev, idx, tmpid, THIS_MODULE,1600				   0, &card);1601 1602		if (err < 0) {1603			dev_err(&pci->dev, "cannot allocate the card %d\n", i);1604			pcxhr_free(mgr);1605			return err;1606		}1607 1608		strcpy(card->driver, DRIVER_NAME);1609		snprintf(card->shortname, sizeof(card->shortname),1610			 "Digigram [PCM #%d]", i);1611		snprintf(card->longname, sizeof(card->longname),1612			 "%s [PCM #%d]", mgr->name, i);1613 1614		err = pcxhr_create(mgr, card, i);1615		if (err < 0) {1616			snd_card_free(card);1617			pcxhr_free(mgr);1618			return err;1619		}1620 1621		if (i == 0)1622			/* init proc interface only for chip0 */1623			pcxhr_proc_init(mgr->chip[i]);1624 1625		err = snd_card_register(card);1626		if (err < 0) {1627			pcxhr_free(mgr);1628			return err;1629		}1630	}1631 1632	/* create hostport purgebuffer */1633	size = PAGE_ALIGN(sizeof(struct pcxhr_hostport));1634	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,1635				size, &mgr->hostport) < 0) {1636		pcxhr_free(mgr);1637		return -ENOMEM;1638	}1639	/* init purgebuffer */1640	memset(mgr->hostport.area, 0, size);1641 1642	/* create a DSP loader */1643	err = pcxhr_setup_firmware(mgr);1644	if (err < 0) {1645		pcxhr_free(mgr);1646		return err;1647	}1648 1649	pci_set_drvdata(pci, mgr);1650	dev++;1651	return 0;1652}1653 1654static void pcxhr_remove(struct pci_dev *pci)1655{1656	pcxhr_free(pci_get_drvdata(pci));1657}1658 1659static struct pci_driver pcxhr_driver = {1660	.name = KBUILD_MODNAME,1661	.id_table = pcxhr_ids,1662	.probe = pcxhr_probe,1663	.remove = pcxhr_remove,1664};1665 1666module_pci_driver(pcxhr_driver);1667