brintos

brintos / linux-shallow public Read only

0
0
Text · 7.3 KiB · af8f495 Raw
281 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * C-Media CMI8788 driver - helper functions4 *5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>6 */7 8#include <linux/delay.h>9#include <linux/sched.h>10#include <linux/export.h>11#include <linux/io.h>12#include <sound/core.h>13#include <sound/mpu401.h>14#include "oxygen.h"15 16u8 oxygen_read8(struct oxygen *chip, unsigned int reg)17{18	return inb(chip->addr + reg);19}20EXPORT_SYMBOL(oxygen_read8);21 22u16 oxygen_read16(struct oxygen *chip, unsigned int reg)23{24	return inw(chip->addr + reg);25}26EXPORT_SYMBOL(oxygen_read16);27 28u32 oxygen_read32(struct oxygen *chip, unsigned int reg)29{30	return inl(chip->addr + reg);31}32EXPORT_SYMBOL(oxygen_read32);33 34void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value)35{36	outb(value, chip->addr + reg);37	chip->saved_registers._8[reg] = value;38}39EXPORT_SYMBOL(oxygen_write8);40 41void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value)42{43	outw(value, chip->addr + reg);44	chip->saved_registers._16[reg / 2] = cpu_to_le16(value);45}46EXPORT_SYMBOL(oxygen_write16);47 48void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value)49{50	outl(value, chip->addr + reg);51	chip->saved_registers._32[reg / 4] = cpu_to_le32(value);52}53EXPORT_SYMBOL(oxygen_write32);54 55void oxygen_write8_masked(struct oxygen *chip, unsigned int reg,56			  u8 value, u8 mask)57{58	u8 tmp = inb(chip->addr + reg);59	tmp &= ~mask;60	tmp |= value & mask;61	outb(tmp, chip->addr + reg);62	chip->saved_registers._8[reg] = tmp;63}64EXPORT_SYMBOL(oxygen_write8_masked);65 66void oxygen_write16_masked(struct oxygen *chip, unsigned int reg,67			   u16 value, u16 mask)68{69	u16 tmp = inw(chip->addr + reg);70	tmp &= ~mask;71	tmp |= value & mask;72	outw(tmp, chip->addr + reg);73	chip->saved_registers._16[reg / 2] = cpu_to_le16(tmp);74}75EXPORT_SYMBOL(oxygen_write16_masked);76 77void oxygen_write32_masked(struct oxygen *chip, unsigned int reg,78			   u32 value, u32 mask)79{80	u32 tmp = inl(chip->addr + reg);81	tmp &= ~mask;82	tmp |= value & mask;83	outl(tmp, chip->addr + reg);84	chip->saved_registers._32[reg / 4] = cpu_to_le32(tmp);85}86EXPORT_SYMBOL(oxygen_write32_masked);87 88static int oxygen_ac97_wait(struct oxygen *chip, unsigned int mask)89{90	u8 status = 0;91 92	/*93	 * Reading the status register also clears the bits, so we have to save94	 * the read bits in status.95	 */96	wait_event_timeout(chip->ac97_waitqueue,97			   ({ status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS);98			      status & mask; }),99			   msecs_to_jiffies(1) + 1);100	/*101	 * Check even after a timeout because this function should not require102	 * the AC'97 interrupt to be enabled.103	 */104	status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS);105	return status & mask ? 0 : -EIO;106}107 108/*109 * About 10% of AC'97 register reads or writes fail to complete, but even those110 * where the controller indicates completion aren't guaranteed to have actually111 * happened.112 *113 * It's hard to assign blame to either the controller or the codec because both114 * were made by C-Media ...115 */116 117void oxygen_write_ac97(struct oxygen *chip, unsigned int codec,118		       unsigned int index, u16 data)119{120	unsigned int count, succeeded;121	u32 reg;122 123	reg = data;124	reg |= index << OXYGEN_AC97_REG_ADDR_SHIFT;125	reg |= OXYGEN_AC97_REG_DIR_WRITE;126	reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT;127	succeeded = 0;128	for (count = 5; count > 0; --count) {129		udelay(5);130		oxygen_write32(chip, OXYGEN_AC97_REGS, reg);131		/* require two "completed" writes, just to be sure */132		if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 &&133		    ++succeeded >= 2) {134			chip->saved_ac97_registers[codec][index / 2] = data;135			return;136		}137	}138	dev_err(chip->card->dev, "AC'97 write timeout\n");139}140EXPORT_SYMBOL(oxygen_write_ac97);141 142u16 oxygen_read_ac97(struct oxygen *chip, unsigned int codec,143		     unsigned int index)144{145	unsigned int count;146	unsigned int last_read = UINT_MAX;147	u32 reg;148 149	reg = index << OXYGEN_AC97_REG_ADDR_SHIFT;150	reg |= OXYGEN_AC97_REG_DIR_READ;151	reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT;152	for (count = 5; count > 0; --count) {153		udelay(5);154		oxygen_write32(chip, OXYGEN_AC97_REGS, reg);155		udelay(10);156		if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_READ_DONE) >= 0) {157			u16 value = oxygen_read16(chip, OXYGEN_AC97_REGS);158			/* we require two consecutive reads of the same value */159			if (value == last_read)160				return value;161			last_read = value;162			/*163			 * Invert the register value bits to make sure that two164			 * consecutive unsuccessful reads do not return the same165			 * value.166			 */167			reg ^= 0xffff;168		}169	}170	dev_err(chip->card->dev, "AC'97 read timeout on codec %u\n", codec);171	return 0;172}173EXPORT_SYMBOL(oxygen_read_ac97);174 175void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,176			      unsigned int index, u16 data, u16 mask)177{178	u16 value = oxygen_read_ac97(chip, codec, index);179	value &= ~mask;180	value |= data & mask;181	oxygen_write_ac97(chip, codec, index, value);182}183EXPORT_SYMBOL(oxygen_write_ac97_masked);184 185static int oxygen_wait_spi(struct oxygen *chip)186{187	unsigned int count;188 189	/*190	 * Higher timeout to be sure: 200 us;191	 * actual transaction should not need more than 40 us.192	 */193	for (count = 50; count > 0; count--) {194		udelay(4);195		if ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) &196						OXYGEN_SPI_BUSY) == 0)197			return 0;198	}199	dev_err(chip->card->dev, "oxygen: SPI wait timeout\n");200	return -EIO;201}202 203int oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data)204{205	/*206	 * We need to wait AFTER initiating the SPI transaction,207	 * otherwise read operations will not work.208	 */209	oxygen_write8(chip, OXYGEN_SPI_DATA1, data);210	oxygen_write8(chip, OXYGEN_SPI_DATA2, data >> 8);211	if (control & OXYGEN_SPI_DATA_LENGTH_3)212		oxygen_write8(chip, OXYGEN_SPI_DATA3, data >> 16);213	oxygen_write8(chip, OXYGEN_SPI_CONTROL, control);214	return oxygen_wait_spi(chip);215}216EXPORT_SYMBOL(oxygen_write_spi);217 218void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data)219{220	/* should not need more than about 300 us */221	msleep(1);222 223	oxygen_write8(chip, OXYGEN_2WIRE_MAP, map);224	oxygen_write8(chip, OXYGEN_2WIRE_DATA, data);225	oxygen_write8(chip, OXYGEN_2WIRE_CONTROL,226		      device | OXYGEN_2WIRE_DIR_WRITE);227}228EXPORT_SYMBOL(oxygen_write_i2c);229 230static void _write_uart(struct oxygen *chip, unsigned int port, u8 data)231{232	if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL)233		msleep(1);234	oxygen_write8(chip, OXYGEN_MPU401 + port, data);235}236 237void oxygen_reset_uart(struct oxygen *chip)238{239	_write_uart(chip, 1, MPU401_RESET);240	msleep(1); /* wait for ACK */241	_write_uart(chip, 1, MPU401_ENTER_UART);242}243EXPORT_SYMBOL(oxygen_reset_uart);244 245void oxygen_write_uart(struct oxygen *chip, u8 data)246{247	_write_uart(chip, 0, data);248}249EXPORT_SYMBOL(oxygen_write_uart);250 251u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index)252{253	unsigned int timeout;254 255	oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,256		      index | OXYGEN_EEPROM_DIR_READ);257	for (timeout = 0; timeout < 100; ++timeout) {258		udelay(1);259		if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)260		      & OXYGEN_EEPROM_BUSY))261			break;262	}263	return oxygen_read16(chip, OXYGEN_EEPROM_DATA);264}265 266void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value)267{268	unsigned int timeout;269 270	oxygen_write16(chip, OXYGEN_EEPROM_DATA, value);271	oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,272		      index | OXYGEN_EEPROM_DIR_WRITE);273	for (timeout = 0; timeout < 10; ++timeout) {274		msleep(1);275		if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)276		      & OXYGEN_EEPROM_BUSY))277			return;278	}279	dev_err(chip->card->dev, "EEPROM write timeout\n");280}281