11f045217Swdenk /* 21f045217Swdenk * (C) Copyright 2001 31f045217Swdenk * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. 41f045217Swdenk * 5*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 61f045217Swdenk * 71f045217Swdenk * The original I2C interface was 81f045217Swdenk * (C) 2000 by Paolo Scaffardi (arsenio@tin.it) 91f045217Swdenk * AIRVENT SAM s.p.a - RIMINI(ITALY) 101f045217Swdenk * but has been changed substantially. 111f045217Swdenk */ 121f045217Swdenk 131f045217Swdenk #ifndef _I2C_H_ 141f045217Swdenk #define _I2C_H_ 151f045217Swdenk 161f045217Swdenk /* 171f045217Swdenk * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 181f045217Swdenk * 191f045217Swdenk * The implementation MUST NOT use static or global variables if the 201f045217Swdenk * I2C routines are used to read SDRAM configuration information 211f045217Swdenk * because this is done before the memories are initialized. Limited 221f045217Swdenk * use of stack-based variables are OK (the initial stack size is 231f045217Swdenk * limited). 241f045217Swdenk * 251f045217Swdenk * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 261f045217Swdenk */ 271f045217Swdenk 281f045217Swdenk /* 291f045217Swdenk * Configuration items. 301f045217Swdenk */ 311f045217Swdenk #define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ 321f045217Swdenk 33cd7b4e82SMarek Vasut #ifdef CONFIG_I2C_MULTI_BUS 34cd7b4e82SMarek Vasut #define MAX_I2C_BUS 2 35cd7b4e82SMarek Vasut #define I2C_MULTI_BUS 1 3679b2d0bbSStefan Roese #else 37cd7b4e82SMarek Vasut #define MAX_I2C_BUS 1 38cd7b4e82SMarek Vasut #define I2C_MULTI_BUS 0 39cd7b4e82SMarek Vasut #endif 40cd7b4e82SMarek Vasut 41cd7b4e82SMarek Vasut #if !defined(CONFIG_SYS_MAX_I2C_BUS) 42cd7b4e82SMarek Vasut #define CONFIG_SYS_MAX_I2C_BUS MAX_I2C_BUS 4379b2d0bbSStefan Roese #endif 4479b2d0bbSStefan Roese 458c12045aSStefan Roese /* define the I2C bus number for RTC and DTT if not already done */ 466d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #if !defined(CONFIG_SYS_RTC_BUS_NUM) 476d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_RTC_BUS_NUM 0 488c12045aSStefan Roese #endif 496d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #if !defined(CONFIG_SYS_DTT_BUS_NUM) 506d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_DTT_BUS_NUM 0 518c12045aSStefan Roese #endif 526d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #if !defined(CONFIG_SYS_SPD_BUS_NUM) 536d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_SPD_BUS_NUM 0 54d8a8ea5cSMatthias Fuchs #endif 558c12045aSStefan Roese 5698aed379SHeiko Schocher #ifndef I2C_SOFT_DECLARATIONS 5798aed379SHeiko Schocher # if defined(CONFIG_MPC8260) 586d0f6bcfSJean-Christophe PLAGNIOL-VILLARD # define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT); 5998aed379SHeiko Schocher # elif defined(CONFIG_8xx) 606d0f6bcfSJean-Christophe PLAGNIOL-VILLARD # define I2C_SOFT_DECLARATIONS volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 610cf0b931SJens Scharsig 620cf0b931SJens Scharsig # elif (defined(CONFIG_AT91RM9200) || \ 630cf0b931SJens Scharsig defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) || \ 640cf0b931SJens Scharsig defined(CONFIG_AT91SAM9263)) && !defined(CONFIG_AT91_LEGACY) 6578132275Sesw@bus-elektronik.de # define I2C_SOFT_DECLARATIONS at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 6698aed379SHeiko Schocher # else 6798aed379SHeiko Schocher # define I2C_SOFT_DECLARATIONS 6898aed379SHeiko Schocher # endif 6998aed379SHeiko Schocher #endif 70ecf5f077STimur Tabi 71ecf5f077STimur Tabi #ifdef CONFIG_8xx 729c90a2c8SPeter Tyser /* Set default value for the I2C bus speed on 8xx. In the 73ecf5f077STimur Tabi * future, we'll define these in all 8xx board config files. 74ecf5f077STimur Tabi */ 75ecf5f077STimur Tabi #ifndef CONFIG_SYS_I2C_SPEED 76ecf5f077STimur Tabi #define CONFIG_SYS_I2C_SPEED 50000 77ecf5f077STimur Tabi #endif 78ecf5f077STimur Tabi #endif 799c90a2c8SPeter Tyser 809c90a2c8SPeter Tyser /* 819c90a2c8SPeter Tyser * Many boards/controllers/drivers don't support an I2C slave interface so 829c90a2c8SPeter Tyser * provide a default slave address for them for use in common code. A real 839c90a2c8SPeter Tyser * value for CONFIG_SYS_I2C_SLAVE should be defined for any board which does 849c90a2c8SPeter Tyser * support a slave interface. 859c90a2c8SPeter Tyser */ 869c90a2c8SPeter Tyser #ifndef CONFIG_SYS_I2C_SLAVE 879c90a2c8SPeter Tyser #define CONFIG_SYS_I2C_SLAVE 0xfe 88ecf5f077STimur Tabi #endif 89ecf5f077STimur Tabi 901f045217Swdenk /* 911f045217Swdenk * Initialization, must be called once on start up, may be called 921f045217Swdenk * repeatedly to change the speed and slave addresses. 931f045217Swdenk */ 941f045217Swdenk void i2c_init(int speed, int slaveaddr); 9506d01dbeSwdenk void i2c_init_board(void); 9626a33504SRichard Retanubun #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT 9726a33504SRichard Retanubun void i2c_board_late_init(void); 9826a33504SRichard Retanubun #endif 991f045217Swdenk 10067b23a32SHeiko Schocher #if defined(CONFIG_I2C_MUX) 10167b23a32SHeiko Schocher 10267b23a32SHeiko Schocher typedef struct _mux { 10367b23a32SHeiko Schocher uchar chip; 10467b23a32SHeiko Schocher uchar channel; 10567b23a32SHeiko Schocher char *name; 10667b23a32SHeiko Schocher struct _mux *next; 10767b23a32SHeiko Schocher } I2C_MUX; 10867b23a32SHeiko Schocher 10967b23a32SHeiko Schocher typedef struct _mux_device { 11067b23a32SHeiko Schocher int busid; 11167b23a32SHeiko Schocher I2C_MUX *mux; /* List of muxes, to reach the device */ 11267b23a32SHeiko Schocher struct _mux_device *next; 11367b23a32SHeiko Schocher } I2C_MUX_DEVICE; 11467b23a32SHeiko Schocher 11567b23a32SHeiko Schocher I2C_MUX_DEVICE *i2c_mux_search_device(int id); 11667b23a32SHeiko Schocher I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf); 11767b23a32SHeiko Schocher int i2x_mux_select_mux(int bus); 11867b23a32SHeiko Schocher int i2c_mux_ident_muxstring_f (uchar *buf); 11967b23a32SHeiko Schocher #endif 12067b23a32SHeiko Schocher 1211f045217Swdenk /* 1221f045217Swdenk * Probe the given I2C chip address. Returns 0 if a chip responded, 1231f045217Swdenk * not 0 on failure. 1241f045217Swdenk */ 1251f045217Swdenk int i2c_probe(uchar chip); 1261f045217Swdenk 1271f045217Swdenk /* 1281f045217Swdenk * Read/Write interface: 1291f045217Swdenk * chip: I2C chip address, range 0..127 1301f045217Swdenk * addr: Memory (register) address within the chip 1311f045217Swdenk * alen: Number of bytes to use for addr (typically 1, 2 for larger 1321f045217Swdenk * memories, 0 for register type devices with only one 1331f045217Swdenk * register) 1341f045217Swdenk * buffer: Where to read/write the data 1351f045217Swdenk * len: How many bytes to read/write 1361f045217Swdenk * 1371f045217Swdenk * Returns: 0 on success, not 0 on failure 1381f045217Swdenk */ 1391f045217Swdenk int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len); 1401f045217Swdenk int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len); 1411f045217Swdenk 1421f045217Swdenk /* 1431f045217Swdenk * Utility routines to read/write registers. 1441f045217Swdenk */ 145ecf5f077STimur Tabi static inline u8 i2c_reg_read(u8 addr, u8 reg) 146ecf5f077STimur Tabi { 147ecf5f077STimur Tabi u8 buf; 148ecf5f077STimur Tabi 149ecf5f077STimur Tabi #ifdef CONFIG_8xx 150ecf5f077STimur Tabi /* MPC8xx needs this. Maybe one day we can get rid of it. */ 151ecf5f077STimur Tabi i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 152ecf5f077STimur Tabi #endif 153ecf5f077STimur Tabi 154ecf5f077STimur Tabi #ifdef DEBUG 155ecf5f077STimur Tabi printf("%s: addr=0x%02x, reg=0x%02x\n", __func__, addr, reg); 156ecf5f077STimur Tabi #endif 157ecf5f077STimur Tabi 158ecf5f077STimur Tabi i2c_read(addr, reg, 1, &buf, 1); 159ecf5f077STimur Tabi 160ecf5f077STimur Tabi return buf; 161ecf5f077STimur Tabi } 162ecf5f077STimur Tabi 163ecf5f077STimur Tabi static inline void i2c_reg_write(u8 addr, u8 reg, u8 val) 164ecf5f077STimur Tabi { 165ecf5f077STimur Tabi #ifdef CONFIG_8xx 166ecf5f077STimur Tabi /* MPC8xx needs this. Maybe one day we can get rid of it. */ 167ecf5f077STimur Tabi i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 168ecf5f077STimur Tabi #endif 169ecf5f077STimur Tabi 170ecf5f077STimur Tabi #ifdef DEBUG 171ecf5f077STimur Tabi printf("%s: addr=0x%02x, reg=0x%02x, val=0x%02x\n", 172ecf5f077STimur Tabi __func__, addr, reg, val); 173ecf5f077STimur Tabi #endif 174ecf5f077STimur Tabi 175ecf5f077STimur Tabi i2c_write(addr, reg, 1, &val, 1); 176ecf5f077STimur Tabi } 1771f045217Swdenk 178bb99ad6dSBen Warren /* 179bb99ad6dSBen Warren * Functions for setting the current I2C bus and its speed 180bb99ad6dSBen Warren */ 181bb99ad6dSBen Warren 182bb99ad6dSBen Warren /* 183bb99ad6dSBen Warren * i2c_set_bus_num: 184bb99ad6dSBen Warren * 185bb99ad6dSBen Warren * Change the active I2C bus. Subsequent read/write calls will 186bb99ad6dSBen Warren * go to this one. 187bb99ad6dSBen Warren * 188bb99ad6dSBen Warren * bus - bus index, zero based 189bb99ad6dSBen Warren * 190bb99ad6dSBen Warren * Returns: 0 on success, not 0 on failure 191bb99ad6dSBen Warren * 192bb99ad6dSBen Warren */ 1939ca880a2STimur Tabi int i2c_set_bus_num(unsigned int bus); 194bb99ad6dSBen Warren 195bb99ad6dSBen Warren /* 196bb99ad6dSBen Warren * i2c_get_bus_num: 197bb99ad6dSBen Warren * 198bb99ad6dSBen Warren * Returns index of currently active I2C bus. Zero-based. 199bb99ad6dSBen Warren */ 200bb99ad6dSBen Warren 2019ca880a2STimur Tabi unsigned int i2c_get_bus_num(void); 202bb99ad6dSBen Warren 203bb99ad6dSBen Warren /* 204bb99ad6dSBen Warren * i2c_set_bus_speed: 205bb99ad6dSBen Warren * 206bb99ad6dSBen Warren * Change the speed of the active I2C bus 207bb99ad6dSBen Warren * 208bb99ad6dSBen Warren * speed - bus speed in Hz 209bb99ad6dSBen Warren * 210bb99ad6dSBen Warren * Returns: 0 on success, not 0 on failure 211bb99ad6dSBen Warren * 212bb99ad6dSBen Warren */ 2139ca880a2STimur Tabi int i2c_set_bus_speed(unsigned int); 214bb99ad6dSBen Warren 215bb99ad6dSBen Warren /* 216bb99ad6dSBen Warren * i2c_get_bus_speed: 217bb99ad6dSBen Warren * 218bb99ad6dSBen Warren * Returns speed of currently active I2C bus in Hz 219bb99ad6dSBen Warren */ 220bb99ad6dSBen Warren 2219ca880a2STimur Tabi unsigned int i2c_get_bus_speed(void); 222bb99ad6dSBen Warren 223cd7b4e82SMarek Vasut /* NOTE: These two functions MUST be always_inline to avoid code growth! */ 224cd7b4e82SMarek Vasut static inline unsigned int I2C_GET_BUS(void) __attribute__((always_inline)); 225cd7b4e82SMarek Vasut static inline unsigned int I2C_GET_BUS(void) 226cd7b4e82SMarek Vasut { 227cd7b4e82SMarek Vasut return I2C_MULTI_BUS ? i2c_get_bus_num() : 0; 228cd7b4e82SMarek Vasut } 229cd7b4e82SMarek Vasut 230cd7b4e82SMarek Vasut static inline void I2C_SET_BUS(unsigned int bus) __attribute__((always_inline)); 231cd7b4e82SMarek Vasut static inline void I2C_SET_BUS(unsigned int bus) 232cd7b4e82SMarek Vasut { 233cd7b4e82SMarek Vasut if (I2C_MULTI_BUS) 234cd7b4e82SMarek Vasut i2c_set_bus_num(bus); 235cd7b4e82SMarek Vasut } 236cd7b4e82SMarek Vasut 2377ca8f73aSŁukasz Majewski /* Multi I2C definitions */ 2387ca8f73aSŁukasz Majewski enum { 2397ca8f73aSŁukasz Majewski I2C_0, I2C_1, I2C_2, I2C_3, I2C_4, I2C_5, I2C_6, I2C_7, 2407ca8f73aSŁukasz Majewski I2C_8, I2C_9, I2C_10, 2417ca8f73aSŁukasz Majewski }; 2427ca8f73aSŁukasz Majewski 2437ca8f73aSŁukasz Majewski /* Multi I2C busses handling */ 2447ca8f73aSŁukasz Majewski #ifdef CONFIG_SOFT_I2C_MULTI_BUS 2457ca8f73aSŁukasz Majewski extern int get_multi_scl_pin(void); 2467ca8f73aSŁukasz Majewski extern int get_multi_sda_pin(void); 2477ca8f73aSŁukasz Majewski extern int multi_i2c_init(void); 2487ca8f73aSŁukasz Majewski #endif 249a9d2ae70SRajeshwari Shinde 250a9d2ae70SRajeshwari Shinde /** 251a9d2ae70SRajeshwari Shinde * Get FDT values for i2c bus. 252a9d2ae70SRajeshwari Shinde * 253a9d2ae70SRajeshwari Shinde * @param blob Device tree blbo 254a9d2ae70SRajeshwari Shinde * @return the number of I2C bus 255a9d2ae70SRajeshwari Shinde */ 256a9d2ae70SRajeshwari Shinde void board_i2c_init(const void *blob); 257a9d2ae70SRajeshwari Shinde 258a9d2ae70SRajeshwari Shinde /** 259a9d2ae70SRajeshwari Shinde * Find the I2C bus number by given a FDT I2C node. 260a9d2ae70SRajeshwari Shinde * 261a9d2ae70SRajeshwari Shinde * @param blob Device tree blbo 262a9d2ae70SRajeshwari Shinde * @param node FDT I2C node to find 263a9d2ae70SRajeshwari Shinde * @return the number of I2C bus (zero based), or -1 on error 264a9d2ae70SRajeshwari Shinde */ 265a9d2ae70SRajeshwari Shinde int i2c_get_bus_num_fdt(int node); 266a9d2ae70SRajeshwari Shinde 267a9d2ae70SRajeshwari Shinde /** 268a9d2ae70SRajeshwari Shinde * Reset the I2C bus represented by the given a FDT I2C node. 269a9d2ae70SRajeshwari Shinde * 270a9d2ae70SRajeshwari Shinde * @param blob Device tree blbo 271a9d2ae70SRajeshwari Shinde * @param node FDT I2C node to find 272a9d2ae70SRajeshwari Shinde * @return 0 if port was reset, -1 if not found 273a9d2ae70SRajeshwari Shinde */ 274a9d2ae70SRajeshwari Shinde int i2c_reset_port_fdt(const void *blob, int node); 2751f045217Swdenk #endif /* _I2C_H_ */ 276