brintos

brintos / linux-shallow public Read only

0
0
Text · 14.9 KiB · bcf1141 Raw
632 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *   ALSA driver for ICEnsemble ICE1712 (Envy24)4 *5 *   Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.16 *7 *	Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>8 */      9 10#include <linux/delay.h>11#include <linux/interrupt.h>12#include <linux/init.h>13#include <linux/slab.h>14#include <sound/core.h>15 16#include "ice1712.h"17#include "envy24ht.h"18#include "revo.h"19 20/* a non-standard I2C device for revo51 */21struct revo51_spec {22	struct snd_i2c_device *dev;23	struct snd_pt2258 *pt2258;24	struct ak4114 *ak4114;25};26 27static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)28{29	/* assert PRST# to converters; MT05 bit 7 */30	outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));31	mdelay(5);32	/* deassert PRST# */33	outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));34}35 36/*37 * change the rate of Envy24HT, AK4355 and AK438138 */39static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)40{41	unsigned char old, tmp, dfs;42	int reg, shift;43 44	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */45		return;46 47	/* adjust DFS on codecs */48	if (rate > 96000)49		dfs = 2;50	else if (rate > 48000)51		dfs = 1;52	else53		dfs = 0;54 55	if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {56		reg = 2;57		shift = 4;58	} else {59		reg = 1;60		shift = 3;61	}62	tmp = snd_akm4xxx_get(ak, 0, reg);63	old = (tmp >> shift) & 0x03;64	if (old == dfs)65		return;66 67	/* reset DFS */68	snd_akm4xxx_reset(ak, 1);69	tmp = snd_akm4xxx_get(ak, 0, reg);70	tmp &= ~(0x03 << shift);71	tmp |= dfs << shift;72	/* snd_akm4xxx_write(ak, 0, reg, tmp); */73	snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */74	snd_akm4xxx_reset(ak, 0);75}76 77/*78 * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)79 */80 81static void revo_i2c_start(struct snd_i2c_bus *bus)82{83	struct snd_ice1712 *ice = bus->private_data;84	snd_ice1712_save_gpio_status(ice);85}86 87static void revo_i2c_stop(struct snd_i2c_bus *bus)88{89	struct snd_ice1712 *ice = bus->private_data;90	snd_ice1712_restore_gpio_status(ice);91}92 93static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)94{95	struct snd_ice1712 *ice = bus->private_data;96	unsigned int mask, val;97 98	val = 0;99	if (clock)100		val |= VT1724_REVO_I2C_CLOCK;	/* write SCL */101	if (data)102		val |= VT1724_REVO_I2C_DATA;	/* write SDA */103	mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA;104	ice->gpio.direction &= ~mask;105	ice->gpio.direction |= val;106	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);107	snd_ice1712_gpio_set_mask(ice, ~mask);108}109 110static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)111{112	struct snd_ice1712 *ice = bus->private_data;113	unsigned int val = 0;114 115	if (clk)116		val |= VT1724_REVO_I2C_CLOCK;117	if (data)118		val |= VT1724_REVO_I2C_DATA;119	snd_ice1712_gpio_write_bits(ice,120				    VT1724_REVO_I2C_DATA |121				    VT1724_REVO_I2C_CLOCK, val);122	udelay(5);123}124 125static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack)126{127	struct snd_ice1712 *ice = bus->private_data;128	int bit;129 130	if (ack)131		udelay(5);132	bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0;133	return bit;134}135 136static struct snd_i2c_bit_ops revo51_bit_ops = {137	.start = revo_i2c_start,138	.stop = revo_i2c_stop,139	.direction = revo_i2c_direction,140	.setlines = revo_i2c_setlines,141	.getdata = revo_i2c_getdata,142};143 144static int revo51_i2c_init(struct snd_ice1712 *ice,145			   struct snd_pt2258 *pt)146{147	struct revo51_spec *spec;148	int err;149 150	spec = kzalloc(sizeof(*spec), GFP_KERNEL);151	if (!spec)152		return -ENOMEM;153	ice->spec = spec;154 155	/* create the I2C bus */156	err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);157	if (err < 0)158		return err;159 160	ice->i2c->private_data = ice;161	ice->i2c->hw_ops.bit = &revo51_bit_ops;162 163	/* create the I2C device */164	err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);165	if (err < 0)166		return err;167 168	pt->card = ice->card;169	pt->i2c_bus = ice->i2c;170	pt->i2c_dev = spec->dev;171	spec->pt2258 = pt;172 173	snd_pt2258_reset(pt);174 175	return 0;176}177 178/*179 * initialize the chips on M-Audio Revolution cards180 */181 182#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }183 184static const struct snd_akm4xxx_dac_channel revo71_front[] = {185	{186		.name = "PCM Playback Volume",187		.num_channels = 2,188		/* front channels DAC supports muting */189		.switch_name = "PCM Playback Switch",190	},191};192 193static const struct snd_akm4xxx_dac_channel revo71_surround[] = {194	AK_DAC("PCM Center Playback Volume", 1),195	AK_DAC("PCM LFE Playback Volume", 1),196	AK_DAC("PCM Side Playback Volume", 2),197	AK_DAC("PCM Rear Playback Volume", 2),198};199 200static const struct snd_akm4xxx_dac_channel revo51_dac[] = {201	AK_DAC("PCM Playback Volume", 2),202	AK_DAC("PCM Center Playback Volume", 1),203	AK_DAC("PCM LFE Playback Volume", 1),204	AK_DAC("PCM Rear Playback Volume", 2),205	AK_DAC("PCM Headphone Volume", 2),206};207 208static const char *revo51_adc_input_names[] = {209	"Mic",210	"Line",211	"CD",212	NULL213};214 215static const struct snd_akm4xxx_adc_channel revo51_adc[] = {216	{217		.name = "PCM Capture Volume",218		.switch_name = "PCM Capture Switch",219		.num_channels = 2,220		.input_names = revo51_adc_input_names221	},222};223 224static const struct snd_akm4xxx akm_revo_front = {225	.type = SND_AK4381,226	.num_dacs = 2,227	.ops = {228		.set_rate_val = revo_set_rate_val229	},230	.dac_info = revo71_front,231};232 233static const struct snd_ak4xxx_private akm_revo_front_priv = {234	.caddr = 1,235	.cif = 0,236	.data_mask = VT1724_REVO_CDOUT,237	.clk_mask = VT1724_REVO_CCLK,238	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,239	.cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,240	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,241	.add_flags = VT1724_REVO_CCLK, /* high at init */242	.mask_flags = 0,243};244 245static const struct snd_akm4xxx akm_revo_surround = {246	.type = SND_AK4355,247	.idx_offset = 1,248	.num_dacs = 6,249	.ops = {250		.set_rate_val = revo_set_rate_val251	},252	.dac_info = revo71_surround,253};254 255static const struct snd_ak4xxx_private akm_revo_surround_priv = {256	.caddr = 3,257	.cif = 0,258	.data_mask = VT1724_REVO_CDOUT,259	.clk_mask = VT1724_REVO_CCLK,260	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,261	.cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,262	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,263	.add_flags = VT1724_REVO_CCLK, /* high at init */264	.mask_flags = 0,265};266 267static const struct snd_akm4xxx akm_revo51 = {268	.type = SND_AK4358,269	.num_dacs = 8,270	.ops = {271		.set_rate_val = revo_set_rate_val272	},273	.dac_info = revo51_dac,274};275 276static const struct snd_ak4xxx_private akm_revo51_priv = {277	.caddr = 2,278	.cif = 0,279	.data_mask = VT1724_REVO_CDOUT,280	.clk_mask = VT1724_REVO_CCLK,281	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,282	.cs_addr = VT1724_REVO_CS1,283	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,284	.add_flags = VT1724_REVO_CCLK, /* high at init */285	.mask_flags = 0,286};287 288static const struct snd_akm4xxx akm_revo51_adc = {289	.type = SND_AK5365,290	.num_adcs = 2,291	.adc_info = revo51_adc,292};293 294static const struct snd_ak4xxx_private akm_revo51_adc_priv = {295	.caddr = 2,296	.cif = 0,297	.data_mask = VT1724_REVO_CDOUT,298	.clk_mask = VT1724_REVO_CCLK,299	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,300	.cs_addr = VT1724_REVO_CS0,301	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,302	.add_flags = VT1724_REVO_CCLK, /* high at init */303	.mask_flags = 0,304};305 306static struct snd_pt2258 ptc_revo51_volume;307 308/* AK4358 for AP192 DAC, AK5385A for ADC */309static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)310{311	struct snd_ice1712 *ice = ak->private_data[0];312	int dfs;313 314	revo_set_rate_val(ak, rate);315 316	/* reset CKS */317	snd_ice1712_gpio_write_bits(ice, 1 << 8, rate > 96000 ? 1 << 8 : 0);318	/* reset DFS pins of AK5385A for ADC, too */319	if (rate > 96000)320		dfs = 2;321	else if (rate > 48000)322		dfs = 1;323	else324		dfs = 0;325	snd_ice1712_gpio_write_bits(ice, 3 << 9, dfs << 9);326	/* reset ADC */327	snd_ice1712_gpio_write_bits(ice, 1 << 11, 0);328	snd_ice1712_gpio_write_bits(ice, 1 << 11, 1 << 11);329}330 331static const struct snd_akm4xxx_dac_channel ap192_dac[] = {332	AK_DAC("PCM Playback Volume", 2)333};334 335static const struct snd_akm4xxx akm_ap192 = {336	.type = SND_AK4358,337	.num_dacs = 2,338	.ops = {339		.set_rate_val = ap192_set_rate_val340	},341	.dac_info = ap192_dac,342};343 344static const struct snd_ak4xxx_private akm_ap192_priv = {345	.caddr = 2,346	.cif = 0,347	.data_mask = VT1724_REVO_CDOUT,348	.clk_mask = VT1724_REVO_CCLK,349	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3,350	.cs_addr = VT1724_REVO_CS3,351	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3,352	.add_flags = VT1724_REVO_CCLK, /* high at init */353	.mask_flags = 0,354};355 356/* AK4114 support on Audiophile 192 */357/* CDTO (pin 32) -- GPIO2 pin 52358 * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)359 * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)360 * CSN  (pin 35) -- GPIO7 pin 59361 */362#define AK4114_ADDR	0x00363 364static void write_data(struct snd_ice1712 *ice, unsigned int gpio,365		       unsigned int data, int idx)366{367	for (; idx >= 0; idx--) {368		/* drop clock */369		gpio &= ~VT1724_REVO_CCLK;370		snd_ice1712_gpio_write(ice, gpio);371		udelay(1);372		/* set data */373		if (data & (1 << idx))374			gpio |= VT1724_REVO_CDOUT;375		else376			gpio &= ~VT1724_REVO_CDOUT;377		snd_ice1712_gpio_write(ice, gpio);378		udelay(1);379		/* raise clock */380		gpio |= VT1724_REVO_CCLK;381		snd_ice1712_gpio_write(ice, gpio);382		udelay(1);383	}384}385 386static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,387			       int idx)388{389	unsigned char data = 0;390 391	for (; idx >= 0; idx--) {392		/* drop clock */393		gpio &= ~VT1724_REVO_CCLK;394		snd_ice1712_gpio_write(ice, gpio);395		udelay(1);396		/* read data */397		if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN)398			data |= (1 << idx);399		udelay(1);400		/* raise clock */401		gpio |= VT1724_REVO_CCLK;402		snd_ice1712_gpio_write(ice, gpio);403		udelay(1);404	}405	return data;406}407 408static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)409{410	unsigned int tmp;411 412	snd_ice1712_save_gpio_status(ice);413	tmp = snd_ice1712_gpio_read(ice);414	tmp |= VT1724_REVO_CCLK; /* high at init */415	tmp |= VT1724_REVO_CS0;416	tmp &= ~VT1724_REVO_CS3;417	snd_ice1712_gpio_write(ice, tmp);418	udelay(1);419	return tmp;420}421 422static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)423{424	tmp |= VT1724_REVO_CS3;425	tmp |= VT1724_REVO_CS0;426	snd_ice1712_gpio_write(ice, tmp);427	udelay(1);428	snd_ice1712_restore_gpio_status(ice);429}430 431static void ap192_ak4114_write(void *private_data, unsigned char addr,432			       unsigned char data)433{434	struct snd_ice1712 *ice = private_data;435	unsigned int tmp, addrdata;436 437	tmp = ap192_4wire_start(ice);438	addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);439	addrdata = (addrdata << 8) | data;440	write_data(ice, tmp, addrdata, 15);441	ap192_4wire_finish(ice, tmp);442}443 444static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)445{446	struct snd_ice1712 *ice = private_data;447	unsigned int tmp;448	unsigned char data;449 450	tmp = ap192_4wire_start(ice);451	write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);452	data = read_data(ice, tmp, 7);453	ap192_4wire_finish(ice, tmp);454	return data;455}456 457static int ap192_ak4114_init(struct snd_ice1712 *ice)458{459	static const unsigned char ak4114_init_vals[] = {460		AK4114_RST | AK4114_PWN | AK4114_OCKS0,461		AK4114_DIF_I24I2S,462		AK4114_TX1E,463		AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0),464		0,465		0466	};467	static const unsigned char ak4114_init_txcsb[] = {468		0x41, 0x02, 0x2c, 0x00, 0x00469	};470	int err;471 472	struct revo51_spec *spec;473	spec = kzalloc(sizeof(*spec), GFP_KERNEL);474	if (!spec)475		return -ENOMEM;476	ice->spec = spec;477 478	err = snd_ak4114_create(ice->card,479				 ap192_ak4114_read,480				 ap192_ak4114_write,481				 ak4114_init_vals, ak4114_init_txcsb,482				 ice, &spec->ak4114);483	if (err < 0)484		return err;485	/* AK4114 in Revo cannot detect external rate correctly.486	 * No reason to stop capture stream due to incorrect checks */487	spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;488 489	return 0;490}491 492static int revo_init(struct snd_ice1712 *ice)493{494	struct snd_akm4xxx *ak;495	int err;496 497	/* determine I2C, DACs and ADCs */498	switch (ice->eeprom.subvendor) {499	case VT1724_SUBDEVICE_REVOLUTION71:500		ice->num_total_dacs = 8;501		ice->num_total_adcs = 2;502		ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;503		break;504	case VT1724_SUBDEVICE_REVOLUTION51:505		ice->num_total_dacs = 8;506		ice->num_total_adcs = 2;507		break;508	case VT1724_SUBDEVICE_AUDIOPHILE192:509		ice->num_total_dacs = 2;510		ice->num_total_adcs = 2;511		break;512	default:513		snd_BUG();514		return -EINVAL;515	}516 517	/* second stage of initialization, analog parts and others */518	ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);519	if (! ak)520		return -ENOMEM;521	switch (ice->eeprom.subvendor) {522	case VT1724_SUBDEVICE_REVOLUTION71:523		ice->akm_codecs = 2;524		err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,525						&akm_revo_front_priv, ice);526		if (err < 0)527			return err;528		err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,529						&akm_revo_surround_priv, ice);530		if (err < 0)531			return err;532		/* unmute all codecs */533		snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,534						VT1724_REVO_MUTE);535		break;536	case VT1724_SUBDEVICE_REVOLUTION51:537		ice->akm_codecs = 2;538		err = snd_ice1712_akm4xxx_init(ak, &akm_revo51,539					       &akm_revo51_priv, ice);540		if (err < 0)541			return err;542		err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc,543					       &akm_revo51_adc_priv, ice);544		if (err < 0)545			return err;546		err = revo51_i2c_init(ice, &ptc_revo51_volume);547		if (err < 0)548			return err;549		/* unmute all codecs */550		snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,551					    VT1724_REVO_MUTE);552		break;553	case VT1724_SUBDEVICE_AUDIOPHILE192:554		ice->akm_codecs = 1;555		err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv,556					       ice);557		if (err < 0)558			return err;559		err = ap192_ak4114_init(ice);560		if (err < 0)561			return err;562		563		/* unmute all codecs */564		snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,565					    VT1724_REVO_MUTE);566		break;567	}568 569	return 0;570}571 572 573static int revo_add_controls(struct snd_ice1712 *ice)574{575	struct revo51_spec *spec = ice->spec;576	int err;577 578	switch (ice->eeprom.subvendor) {579	case VT1724_SUBDEVICE_REVOLUTION71:580		err = snd_ice1712_akm4xxx_build_controls(ice);581		if (err < 0)582			return err;583		break;584	case VT1724_SUBDEVICE_REVOLUTION51:585		err = snd_ice1712_akm4xxx_build_controls(ice);586		if (err < 0)587			return err;588		spec = ice->spec;589		err = snd_pt2258_build_controls(spec->pt2258);590		if (err < 0)591			return err;592		break;593	case VT1724_SUBDEVICE_AUDIOPHILE192:594		err = snd_ice1712_akm4xxx_build_controls(ice);595		if (err < 0)596			return err;597		/* only capture SPDIF over AK4114 */598		err = snd_ak4114_build(spec->ak4114, NULL,599		   ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);600		if (err < 0)601			return err;602		break;603	}604	return 0;605}606 607/* entry point */608struct snd_ice1712_card_info snd_vt1724_revo_cards[] = {609	{610		.subvendor = VT1724_SUBDEVICE_REVOLUTION71,611		.name = "M Audio Revolution-7.1",612		.model = "revo71",613		.chip_init = revo_init,614		.build_controls = revo_add_controls,615	},616	{617		.subvendor = VT1724_SUBDEVICE_REVOLUTION51,618		.name = "M Audio Revolution-5.1",619		.model = "revo51",620		.chip_init = revo_init,621		.build_controls = revo_add_controls,622	},623	{624		.subvendor = VT1724_SUBDEVICE_AUDIOPHILE192,625		.name = "M Audio Audiophile192",626		.model = "ap192",627		.chip_init = revo_init,628		.build_controls = revo_add_controls,629	},630	{ } /* terminator */631};632