Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

misc: eeprom_93xx46: Add quirk to support Microchip 93LC46B eeprom

A dummy zero bit is sent preceding the data during a read transfer by the
Microchip 93LC46B eeprom (section 2.7 of[1]). This results in right shift
of data during a read. In order to ignore this bit a quirk can be added to
send an extra zero bit after the read address.

Add a quirk to ignore the zero bit sent before data by adding a zero bit
after the read address.

[1] - https://www.mouser.com/datasheet/2/268/20001749K-277859.pdf

Signed-off-by: Aswath Govindraju <a-govindraju@ti.com>
Link: https://lore.kernel.org/r/20210105105817.17644-3-a-govindraju@ti.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Aswath Govindraju and committed by
Greg Kroah-Hartman
f6f1f8e6 68058229

+17
+15
drivers/misc/eeprom/eeprom_93xx46.c
··· 35 35 EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH, 36 36 }; 37 37 38 + static const struct eeprom_93xx46_devtype_data microchip_93lc46b_data = { 39 + .quirks = EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE, 40 + }; 41 + 38 42 struct eeprom_93xx46_dev { 39 43 struct spi_device *spi; 40 44 struct eeprom_93xx46_platform_data *pdata; ··· 57 53 static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) 58 54 { 59 55 return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; 56 + } 57 + 58 + static inline bool has_quirk_extra_read_cycle(struct eeprom_93xx46_dev *edev) 59 + { 60 + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE; 60 61 } 61 62 62 63 static int eeprom_93xx46_read(void *priv, unsigned int off, ··· 104 95 105 96 dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", 106 97 cmd_addr, edev->spi->max_speed_hz); 98 + 99 + if (has_quirk_extra_read_cycle(edev)) { 100 + cmd_addr <<= 1; 101 + bits += 1; 102 + } 107 103 108 104 spi_message_init(&m); 109 105 ··· 377 363 static const struct of_device_id eeprom_93xx46_of_table[] = { 378 364 { .compatible = "eeprom-93xx46", }, 379 365 { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, 366 + { .compatible = "microchip,93lc46b", .data = &microchip_93lc46b_data, }, 380 367 {} 381 368 }; 382 369 MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table);
+2
include/linux/eeprom_93xx46.h
··· 16 16 #define EEPROM_93XX46_QUIRK_SINGLE_WORD_READ (1 << 0) 17 17 /* Instructions such as EWEN are (addrlen + 2) in length. */ 18 18 #define EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH (1 << 1) 19 + /* Add extra cycle after address during a read */ 20 + #define EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE BIT(2) 19 21 20 22 /* 21 23 * optional hooks to control additional logic