Quark GPIO and I2C (ESP – Fall 2014) Computer Science & Engineering Department Arizona State University Tempe, AZ 85287 Dr. Yann-Hang Lee yhlee@asu.edu (480) 727-7507 Real-time Systems Lab, Computer Science and Engineering, ASU GPIO interface From programmer’s view GPIO pin numbering enable GPIO (pin multiplexing) set direction read/write data interrupt There may be various physical connections GPIO pins in IO expender GPIO ports GPIO devices on PCI bus various GPIO controllers GPIO driver (user-level interface) : /driver/gpio/gpiolib.c Drivers for gpio chips For Galileo board: gpio_sch.c (Poulsbo SCH) + intel_cln_gip_gpio.c + cy8c9540a.c Real-time Systems Lab, Computer Science and Engineering, ASU 1 GPIO Sysfs Interface Example of shell commands for GPIO: echo -n $led > /sys/class/gpio/export echo -n $DIR > /sys/class/gpio/gpio$led/direction echo -n $ON > /sys/class/gpio/gpio$led/value Sysfs interface to export kernel data structures, their attributes, and the linkages between them to user space. two methods for read and write operations struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, ….); ssize_t (*store)(struct device *dev, ….); }; So, in gpiolib.c, the following functions are provided export_store(), gpio_value_store(), gpio_direction_show(), …. Real-time Systems Lab, Computer Science and Engineering, ASU 2 Linux GPIO Driver A GPIO (General Purpose Input/Output) pin can be configured, set up its direction, and value if it is an output pin A SoC chip may have several GPIO components Multiple “gpio chips” A global number in the integrated GPIO namespace, i.e., 0, 1, 2,…,n sysfs interface to user space GPIO framework (gpiolib.c) CY8C9540A 40 GPIO pins in 6 ports Quark GIP controller Quark legacy GPIO[7:0] GPIO_SUS[5:0] GPIO[9:8] GPIO Real-time Systems Lab, Computer Science and Engineering, ASU 3 GPIO on Galileo (1) Quark X1000 Sysfs GPIO # Signal Name / Arduino Port # Function and Comments GPIO_SUS0 GPIO_SUS1 GPIO_SUS2 gpio2 gpio3 gpio4 INT_N_S3 GP LED LVL_OE Don’t touch, or bad things will happen :-) LED between CY8C9540A and RTC battery TXS0108E level shifter output enable. GPIO_SUS3 gpio5 GPIO_SUS3_PCIE_RESET_N Reset to Mini PCI-E slot GPIO_SUS4 gpio6 GPIO_SUS4_W_DISABLE_N Wireless disable (RF Kill to PCI-E Slot) GPIO_SUS5 gpio7 A0_N Jumper J2 (Cypress CY8C9540A I2C address select) GPIO0 GPIO1 gpio8 gpio9 SPI0_CS_N Not Connected Select SPI for AD7298 GPIO2 gpio10 SPI1_CS_N Routed to IO10 if selected by IO10_MUX GPIO3 GPIO4 GPIO5 GPIO6 GPIO7 GPIO8 GPIO9 gpio11 gpio12 gpio13 gpio14 gpio15 gpio0 gpio1 Not Connected XRES INT_N_S0 IO2 IO3 GLN_IO2_PU_EN GLN_IO3_PU_EN Reset to Cypress CY8C9540A Don’t touch too :-) Selected by IO2_MUX (gpio31=0) Selected by IO3_MUX (gpio30=0) Enable pullup on IO2/GPIO6 Enable pullup on IO3/GPIO7 Real-time Systems Lab, Computer Science and Engineering, ASU 4 GPIO on Galileo (1) CY8C9540A Sysfs GPIO Signal Name / # Arduino Port # GPORT0_BIT0 gpio16 IO10 GPORT0_BIT1 gpio17 IO5 GPORT0_BIT2 gpio18 IO3 GPORT0_BIT3 gpio19 IO9 GPORT0_BIT4 gpio20 A5_MUX GPORT0_BIT5 gpio21 A4_MUX GPORT0_BIT6 gpio22 A3_MUX GPORT0_BIT7 gpio23 A2_MUX GPORT1_BIT0 gpio24 IO6 GPORT1_BIT1 gpio25 IO11 GPORT1_BIT2 gpio26 IO8 Function and Comments Selected by IO10_MUX (GPORT3_BIT6, gpio42) Also controlled by pwm7 Also controlled by pwm5 Selected by IO3_MUX (gpio30=1) Also controlled by pwm3 Also controlled by pwm1 A5 pin routing: 0 = AD7298 (VIN5) 1 = Cypress CY8C9540A (GPORT4_BIT5, gpio49) A4 pin routing: 0 = AD7298 (VIN4) 1 = Cypress CY8C9540A (GPORT4_BIT4, gpio48) A3 pin routing: 0 = AD7298 (VIN3) 1 = Cypress CY8C9540A (GPORT4_BIT3, gpio47) A2 pin routing: 0 = AD7298 (VIN2) 1 = Cypress CY8C9540A (GPORT4_BIT2, gpio46) Also controlled by pwm6 Selected by IO11_MUX (GPORT3_BIT7, gpio43) Also controlled by pwm4 Real-time Systems Lab, Computer Science and Engineering, ASU 5 GPIO on Galileo (2) Real-time Systems Lab, Computer Science and Engineering, ASU 6 GPIO Chip Driver A driver for each GPIO controller to provide methods to establish GPIO direction and to access GPIO values method to return the IRQ number associated to a given GPIO flag saying whether calls to its methods may sleep optional base number In intel_qrk_gip_gpio.c /* The base GPIO number under GPIOLIB framework */ #define INTEL_QRK_GIP_GPIO_BASE 8 /* The default number of South-Cluster GPIO on Quark. */ #define INTEL_QRK_GIP_NGPIO 8 In include/linux/gpio/driver.h, “gpio_chip” is defined, including base: identifies the first GPIO number handled by this chip. ngpio: the number of GPIOs handled by this controller; the last GPIO handled is (base + ngpio - 1). Real-time Systems Lab, Computer Science and Engineering, ASU 7 Binding of GPIOs to Pins Example: gpio 26 is bit 2 of port 1 in CY8C9540A chip Each GPIO chip is represented by “struct gpio_chip” standard methods such as get, set, etc. “int base;” and “u16 ngpio;” When a gpio chip is added, use “base” and “ngpio” to determine “pin range” of the chip In cy8C9540a.c #define NGPIO 40 static const u8 cy8c9540a_port_offs[] = {0, 8, 16, 20, 28, 36,}; #define GPIO_BASE_ID 16 When cy8c9540a_gpio_get_value is called, an input argument: gpio=26 invoke cypress_get_port(26) to find port 1 invoke cypress_get_offs(26) to find bit 2 Real-time Systems Lab, Computer Science and Engineering, ASU 8 GPIO Driver Operation GPIO chip driver request to add “gpio_chip” to the platform gc->base = pdata->gpio_base; gc->ngpio = NGPIO; ret = gpiochip_add(&dev->gpio_chip); gpiolib.c exports methods to work on GPIO pins from GPIO # to find chip and to invoke teh corresponding methods provided by the chip gpio_request_one(LED1, GPIOF_OUT_INIT_LOW, "led1"); gpio_desc desc1 = gpio_to_desc(LED1); gpio_set_value(desc1, data); sysfs gpio interfaces, such as gpiod_export, gpio_unexport, gpiod_set_value, gpio_direction_input Real-time Systems Lab, Computer Science and Engineering, ASU 9 GPIO Programming GPIO Programming In user space – via sysfs int fd = open("/sys/class/gpio/export", O_WRONLY); sprintf(buffer, "%d", gpio); // int gpio write(fd, buffer, strlen(buffer)); close(fd); In kernel space – use the exported interface of gpiolib.c gpio_request_one(GP_3, GPIOF_OUT_INIT_LOW, "led1"); gpio_set_value(GP_3, 0); Poll and GPIO interrupt configure GPIO pin as an interrupt source via /sys/class/gpio/gpioX/edge poll() system call to block on the gpio value until an interrupt occurs. When the content changes, poll will return POLLERR|POLLPRI. Real-time Systems Lab, Computer Science and Engineering, ASU 10 GIP controller in Quark A PCI device: B:0, D:21, F:2 MMIO – use two base registers in configuration registers Offset Start 10h 14h Offset End 13h 17h Register ID BAR0 BAR1 Default Value 00000000h 00000000h I2C memory registers – BAR0+offset I2C Master mode operation Disable the I2C controller by writing 0 to IC_ENABLE.ENABLE. Write to the IC_CON register Write to the IC_TAR register. Enable the I2C controller by writing a 1 in IC_ENABLE. Write the transfer direction and data to be sent to the IC_DATA_CMD register. Real-time Systems Lab, Computer Science and Engineering, ASU 11 Quark GPIO IRQ Enable in GIP Allows each bit of Port A to be configured for interrupts. In drivers/mfd/intel_cln_gip_gpio.c, #define PORTA_INT_EN 0x30/* Interrupt enable */ #define PORTA_INT_MASK 0x34/* Interrupt mask */ #define PORTA_INT_TYPE_LEVEL 0x38/* Interrupt level*/ ....... static void intel_cln_gpio_irq_enable(struct irq_data *d) {.... void __iomem *reg_inte = reg_base + PORTA_INT_EN; gpio = d->irq - irq_base; spin_lock_irqsave(&lock, flags); val_inte = ioread32(reg_inte); iowrite32(val_inte | BIT(gpio % 32), reg_inte); spin_unlock_irqrestore(&lock, flags); } Real-time Systems Lab, Computer Science and Engineering, ASU 12 Bit-Transfer on I2C Bus One clock pulse is generated for each data bit that is transferred Data Validity The data on the SDA line must be stable during the HIGH(1) period of the clock. The data line(SDA) can change data only when the clock signal (SCL) is LOW(0) Wired-and function open-drain or opencollector Real-time Systems Lab, Computer Science and Engineering, ASU 13 Data Transfer With 7-Bit Device Address After START condition (S), a slave address(7-bit) is sent. A read/write (R/W’) direction is then sent(8th bit) Data transfer occurs, and then always terminated by STOP condition. However, repeated START conditions can occur. Real-time Systems Lab, Computer Science and Engineering, ASU 14 Master-Transmitter to Slave-Receiver Data Transfer In this, the transmission direction never changes. The set-up and transfer is straight-forward Real-time Systems Lab, Computer Science and Engineering, ASU 15 Master-Receiver and Slave-Transmitter Data Transfer Master initiates the data transfer by generating the START condition followed by the start byte (with read/write bit set to 1 i.e. read mode) After the first ack from the slave, the direction of data changes and the master becomes receiver and slave transmitter. The STOP condition is still generated by the master (master sends notACK before generating the STOP) Real-time Systems Lab, Computer Science and Engineering, ASU 16 Example I2C Device – 24FC256 EEPROM 32K bytes in 512 pages of 64 bytes I2C interface with A2, A1, A0 address pins Page write operation: Random read operation: Real-time Systems Lab, Computer Science and Engineering, ASU 17 I2C Controller in Quark GIP controller: Bus 0, Device 21, Function 2 PCI configuration registers Base Address Register (BAR0) — Offset 10h Base Address Register (BAR1) — Offset 14h I2C Controller Memory Mapped Registers – Based on BAR0 register offsets are defined in /deriver/i2c/buses/i2c-designware-core.c I2C algorithm static struct i2c_algorithm i2c_dw_algo = { .master_xfer = i2c_dw_xfer, .functionality = i2c_dw_func, }; major steps of i2c_dw_xfer in i2c-designware-core.c, i2c_dw_wait_bus_not_busy(dev); i2c_dw_xfer_init(dev); /* wait for tx to complete */ wait_for_completion_interruptible_timeout to write to control reg: dw_writel(dev, 1, DW_IC_ENABLE); /* Enable the adapter */ Real-time Systems Lab, Computer Science and Engineering, ASU 18 I2C Drivers in Linux A driver for I2C bus adapter and algorithm drivers manages I2C bus transactions Drivers for I2C devices A client has the device’s I2C bus address and a pointer to a driver which is attached with an adapter When a user program issues a file operation that needs an I2C transaction i2C_transfer (i2C-core.c) to invoke adap_algo_master_xfer command or data is in an msg array the adapter issues reads/writes to hardware I/O addresses. (https://i2c.wiki.kernel.org/index.php/Driver_Architecture) Real-time Systems Lab, Computer Science and Engineering, ASU 19 I2C and SMBus In general, a system can have multiple I2C buses via different adapters and many I2C devices 2-wire synchronous serial buses Master and slave, addressable Processor ICH8 SMBus PCI bus PCI to I2c I2C bus and SMBus Adapter EEPROM compatible with each other. I2C Differences EEPROM Timeout (in SMBus, reset interfaces when sensor clock is low forlonger than 35ms)) Maximum clock speed: 100MHz(Smbus) but I2C bus has both 400kHz and 3.4MHz versions. Logic level: 1: 3V in I2C and 2.1V in SMBus General call and alert response. Real-time Systems Lab, Computer Science and Engineering, ASU 20 Example of Accessing I2C/SMBus Devices i2c_smbus_xfer(adapter, addr, …., data) user program device driver I2C core I2C algorithm I2C adapter read(……) I2C device I2C bus signals 12c_dw_xfer(adapter, msg[ ], num) user space kernel space adapter->algo->i2c_transfer(adapter, msg, num); // for each i2c device struct i2c_client { unsigned short flags; unsigned short addr; char name[I2C_NAME_SIZE]; struct i2c_adapter * adapter; struct i2c_driver * driver; struct device dev; int irq; struct list_head list; struct completion released; }; Real-time Systems Lab, Computer Science and Engineering, ASU 21 Driver Operations (1) When intel_cln_gip_core module is installed, register itself as a PCI driver provide the probe callback function intel_cln_gip_probe which calls intel_cln_i2c_probe of intel_cln_gip_i2c.c to initiate gip i2c controller In intel_cln_i2c_probe construct and initiate a struct dw_i2c_dev to model dw_i2c controller register it as a i2c adapter and add callback functions struct i2c_adapter /* to identify a physical i2c bus */ struct i2c_algorithm /* the algorithm to access the bus*/ i2c-dev – a char device driver to access all devices on an i2c adapter from userspace user programs call “read”, “write”, “ioctl”, etc., to control i2c bus transactions on an adapter (master). Real-time Systems Lab, Computer Science and Engineering, ASU 22 Driver Operations (2) i2c-dev creates a device i2c-x for each i2c adapter where “x” is the adapter number, starting from 0. So, user program can open /dev/i2c-0 set slave address, i.e. client->addr (the i2c address of the device on the bus) write a “msg” to the bus with i2c_transfer in i2c-core.c which eventually calls adap->algo->master_xfer In i2c_dw_xfer, lock the device check bus busy or not start the transfers -- i2c_dw_xfer_init wait for completion In i2c_dw_isr (isr for GIP i2c controller) indicates the completion of a transfer (complete(&dev->cmd_complete)) Real-time Systems Lab, Computer Science and Engineering, ASU 23