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