GPIO Driver and Driver Binding

Slides:



Advertisements
Similar presentations
Lecture 101 Lecture 10: Kernel Modules and Device Drivers ECE 412: Microcomputer Laboratory.
Advertisements

Device Drivers. Linux Device Drivers Linux supports three types of hardware device: character, block and network –character devices: R/W without buffering.
RT_FIFO, Device driver.
purpose Search : automation methods for device driver development in IP-based embedded systems in order to achieve high reliability, productivity, reusability.
USERSPACE I/O Reporter: R 張凱富.
Real-time Systems Lab, Computer Science and Engineering, ASU Please Standby Galileo Tech Talk at ASU Will Begin Shortly.
Wang Lei Chapter 5 Device Management Chapter 5 Device Management — for the Solaris Platform.
Interrupts What is an interrupt? What does an interrupt do to the “flow of control” Interrupts used to overlap computation & I/O – Examples would be console.
Dr. Kimberly E. Newman Hybrid Embedded wk3 Fall 2009.
INPUT/OUTPUT ORGANIZATION INTERRUPTS CS147 Summer 2001 Professor: Sin-Min Lee Presented by: Jing Chen.
Computer System Laboratory
©Alex Doboli Chapter 3: Hardware and Software Subsystems of Mixed-Signal Architectures (Part II) Alex Doboli, Ph.D. Department of Electrical and Computer.
Operating System Program 5 I/O System DMA Device Driver.
Current Processor Design
Hands-On Microsoft Windows Server 2008
Interrupt Handling Sarah Diesburg COP Interrupt Handling One big responsibility of an operating system is to handle hardware connected to the machine.
Real-time Systems Lab, Computer Science and Engineering, ASU Linux Input Systems (ESP – Fall 2014) Computer Science & Engineering Department Arizona State.
GPIO interface From programmer’s view
Khaled A. Al-Utaibi  Interrupt-Driven I/O  Hardware Interrupts  Responding to Hardware Interrupts  INTR and NMI  Computing the.
7/23 Interrupt Controller and Edge Port in Coldfire Computer Science & Engineering Department Arizona State University Tempe, AZ Dr. Yann-Hang Lee.
NT Kernel CS Spring Overview Interrupts and Exceptions: Trap Handler Interrupt Request Levels and IRT DPC’s, and APC’s System Service Dispatching.
LAB 12: Timer and Interrupt Chung-Ta King National Tsing Hua University CS 4101 Introduction to Embedded Systems.
Lab 13 Department of Computer Science and Information Engineering National Taiwan University Lab13 – Interrupt + Timer 2014/12/23 1 /16.
Real-time Systems Lab, Computer Science and Engineering, ASU Quark SPI Interface (ESP – Fall 2014) Computer Science & Engineering Department Arizona State.
Timers and Interrupts Anurag Dwivedi. Let Us Revise.
7/23 Coldfire 5211 Signals and IO Multiplexing Computer Science & Engineering Department Arizona State University Tempe, AZ Dr. Yann-Hang Lee
Preemptive Context Switching
Interfacing Device Drivers with the Kernel
COMP 3438 – Part I - Lecture 5 Character Device Drivers
Linux kernel TLV meetup, Kfir Gollan. What is hardware probing? Different approaches for detecting hardware Probing in the linux kernel.
1 Device Controller I/O units typically consist of A mechanical component: the device itself An electronic component: the device controller or adapter.
Ch 6. Interrupts and Interrupt Handlers. Overview (1) A primary responsibility of the kernel is managing the hardware connected to the machine  The kernel.
Interrupts and Interrupt Handling David Ferry, Chris Gill CSE 522S - Advanced Operating Systems Washington University in St. Louis St. Louis, MO
Lecture 7 Interrupt ,Trap and System Call
Linux Sound Drivers Framework
MQX GPIO.
Linux Device Model A device model after 2.5
Big Picture of Linux Probe and Trace Tools
Preemptive Context Switching
Interrupts and Interrupts Handling
Linux Kernel Development - Robert Love
Why VT-d Direct memory access (DMA) is a method that allows an input/output (I/O) device to send or receive data directly to or from the main memory, bypassing.
Dr. Yann-Hang Lee (480) Quark, PCI, and GPIO Computer Science & Engineering Department Arizona State University Tempe, AZ
CS501 Advanced Computer Architecture
Microprocessor Systems Design I
UNIT – Microcontroller.
Operating Systems (CS 340 D)
Refer to Chapter 10 in the reference book
Computer Architecture
Input/Output.
NS Training Hardware.
BVM Engineering College Electrical Engineering Department : Microprocessor and Microcontroller Interfacing Interrupts of 8051 Prepared by:
CS 286 Computer Organization and Architecture
The PCI bus (Peripheral Component Interconnect ) is the most commonly used peripheral bus on desktops and bigger computers. higher-level bus architectures.
Quark SOC and Galileo Architecture (ESP – Fall 2014)
Zephyr Device Driver and Device Model
Interrupts and Interrupt Handling
ChipScope Pro Software
Top Half / Bottom Half Processing
Linux Kernel Programming CIS 4930/COP 5641
How & When The Kernel Runs
ChipScope Pro Software
Wireless Embedded Systems
Introduction to Linux Device Drivers
COMP3221: Microprocessors and Embedded Systems
Interrupts and Interrupt Handling
Chapter 13: I/O Systems.
The Programmable Peripheral Interface (8255A)
Interrupt Message Store
Chapter 13: I/O Systems “The two main jobs of a computer are I/O and [CPU] processing. In many cases, the main job is I/O, and the [CPU] processing is.
Presentation transcript:

GPIO Driver and Driver Binding Computer Science & Engineering Department Arizona State University Tempe, AZ 85287 Dr. Yann-Hang Lee yhlee@asu.edu (480) 727-7507

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) IO expanders Quark GIP controller Quark legacy GPIO GPIO_SUS[5:0] GPIO[9:0] GPIO[….] chip drivers

Software Components for Galileo Gen2 GPIO /linux/driver/gpio/gpiolib.c the core program for gpio subsystem (framework) /linux/driver/mfd/intel_qrk_gip_core.c the dontroller for gip device on PCI bus /linux/driver/mfd/intel_qrk_gip_gpio.c gpio chip controller for gip_gpio /linux/driver/gpio/gpio-pca953x.c gpio chip controller for I2c expander pca9535 /linux/driver/i2c/busses/i2c-designware-core.c i2c bus controller for designware i2c controller /linux/driver/mfd/intel-qrk-gip_i2c.c a warpper to connect to i2c_designware_core.c /linux/driver/gpio/gpio-sch.c gpio chip controller for gpio port in Poulsbo SCH (system control hub) /linux/driver/platform/x86/quark/intel_qrk_board_data.c /linux/driver/platform/x86/quark/intel_qrk_plat_galileo_gen2.c

GPIO Chip Driver(1) A driver for each type of 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/asm-generic/gpio.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).

GPIO Chip Driver(2) gpio_chip includes function pointers to operate a gpio chip int (*get)(struct gpio_chip *chip, unsigned offset); void (*set)(struct gpio_chip *chip, unsigned offset, int value); int (*direction_input)(struct gpio_chip *chip, unsigned offset); ……. So, we can invoke operations at each pin of a gpio chip When a gpio chip driver is installed register itself to the bus it attached (e.g. PCI or i2c) The callback “probe” function is invoked to initialize struct gpio_chip, then to add gpio_chip /driver/mfd/intel_qrk_gip_gpio.c for gip_gpio /driver/gpio/gpio_pca953x.c for pca9535 chips

Binding of GPIOs to Pins Example: gpio 26 is bit 10 of the 1st PCAL9535 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 intel_qrk_plt_galileo_gen2.c, define gpio_base When pca953x_setup_gpio() is invoked, ngpio is set, When pca953x_gpio_get_value() is called, an input argument: gpio=26 use container_of to find the chip (there are 3 PCAL9535) invoke pca953x_read_reg(chip, offset, &reg_val) to read input reg check the bit and return 1 or 0

IO Expenders in Galileo Gen 1 & 2 Gen 1 – CY8C9540A Gen 2 – 3 PCAL9535 Both connected to quark processor via I2C bus How does the Linux know board configuration Read BIOS DMI data to identify the board Then, register the board (platform_device_register() in linux/drivers/platform/x86/quark/intel_qrk_board_data.c) Once the board is registered, find the platform_driver for "GalileoGen2“, i.e., intel_qrk_plat_galileo_gen2.c In the platform (board) driver, 3 PCA9535 chips are defined and then probed. strlcpy(probed_i2c_pcal9555a_exp0.type, "pcal9555a", I2C_NAME_SIZE); client = i2c_new_probed_device(i2c_adap, &probed_i2c_pcal9555a_exp0, pcal9555a_exp0_i2c_addr, i2c_probe);

Binding of GPIO Adapter and Driver (1) Case 1: pca9535 instantiate the devices --- add 3 pca9535 devices as i2c clients in intel_qrk_plat_galileo_gen2.c (call to i2c_new_device()) initiate pca953x driver – static int __init pca953x_init(void) { return i2c_add_driver(&pca953x_driver); } then invoke i2c_register_driver and eventually pca953x_probe () if found matching devices In the probe function pca953x_setup_gpio device_pca953x_init gpiochip_add driver_register bus_add_driver driver_attach __driver_attach for each device on bus driver_probe_device if matches really_probe dev->bus->probe (i.e. i2c_device_probe) pca953x_probe

Binding of GPIO Adapter and Driver (2) Case 2: gip_gpio instantiate the devices --- pci device initialization initiate intel_qrk_gip_core driver – static int intel_qrk_gip_init(void) { return pci_register_driver(&intel_qrk_gip_driver); } then invoke pci_register_driver and eventually intel_qrk_gip_probe () and then pci_enable_device (for gip) and intel_qrk_gpio_probe In the probe function set up a gpio_chip struct gpiochip_add

GPIO Driver Operation in gpio core 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 the 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

GPIO Interrupts (1) Interrupts from gip_gpio One interrupt source from gip controller GIP ISR is requested in intel_qrk_gip_probe() request_irq(pdev->irq, intel_qrk_gip_handler, IRQF_SHARED, "intel_qrk_gip", gip_drvdata); The handler calls i2c_dw_isr() and intel_qrk_gpio_isr() In intel_qrk_gpio_isr(), Check any pending interrupts (triggered) pin  gpio  irq  desc  desc->handle_irq(desc); irq_desc to keep track of interrupt request source and manage IRQ flow. A list of irq actions and an action may be called when the irq occurs gpio_chip: include irq_chip as the driver for interrupt controller (to manage hardware) To receive a gpio interrupt, an isr (action) must be registered for the irq with proper triggering flag.

GPIO Interrupts (2) In gpio sysfs interface, setting an edge type enables interrupt gpio_edge_store()  gpio_setup_irq()  request_any_context_irq(irq, gpio_sysfs_irq, irq_flags, "gpiolib", value_sd);  request_threaded_irq(irq, NULL, handler, flags, name, dev_id); (or request_irq(…))  an action is allocated  __setup_irq(irq, desc, action); The handler static irqreturn_t gpio_sysfs_irq(int irq, void *priv)  to wake up threads in polling list (of sysfs dir) A similar approach irq_no = gpio_to_irq(GPIO_X); // get the irq number from Linux gpio number request_irq(irq_no, isr_handler, TRIGGER_FLAG, “name", NULL); Use irq_set_irq_type() to reset flags

Linux Kernel Thread A way to implement background tasks inside the kernel static struct task_struct *tsk; static int thread_function(void *data) { int time_count = 0; do { printk(KERN_INFO "thread_function: %d times", ++time_count); msleep(1000); }while(!kthread_should_stop() && time_count<=30); return time_count; } static int hello_init(void) { tsk = kthread_run(thread_function, NULL, "mythread%d", 1); if (IS_ERR(tsk)) { …. } kthread_run()  kthread_create() + wake_up_process()  create a kthread_create_info wake_up kthreadd_task  kthreadd_task calls create_kthread()  kernel_thread()  do_fork ()

Platform Drivers platform_driver_register(&my_pdevice_of_driver ); The driver’s probe function invoked when a platform device is registered and it's device name matches the name specified on the device driver. Initializes and registers the device(s) static const struct platform_device_id my_pdevice_id_table[] = { { "basic-mmio-gpio", }, { "basic-mmio-gpio-be", }, {}, }; MODULE_DEVICE_TABLE(platform, my_pdevice_id_table); static struct platform_driver my_pdevice_driver = { .driver = { .name = "my_pdevice”, .owner = THIS_MODULE, .of_match_table = of_match_ptr(my_pdevice_of_match), }, ,id_table = my_pdevice_id_table, .probe = my_pdevice_probe, .remove = my_pdevice_remove, }; module_platform_driver(my_pdevice_of_driver);

Platform Devices platform_device Once a platform device is declared, name, used in driver binding, a list of resources Once a platform device is declared, init device structure after attached to platform_bus (a virtual bus) device_add(&pdev->dev)  bus_probe_device(dev)  device_attach(dev)  bus_for_each_drv(dev->bus, NULL, dev, __device_attach)  driver_match_device(drv, dev)  drv->bus->match(dev, drv)  given “platform_bus_type”,  platform_match(dev, drv)  driver_probe_device(drv, dev) struct platform_device { const char *name; u32 id; struct device dev; u32 num_resources; struct resource *resource; }; int platform_device_register(struct platform_device *pdev) { device_initialize(&pdev->dev); return platform_device_add(pdev); }

Platform_match if (pdev->driver_override) return !strcmp(pdev->driver_override, drv->name); if (of_driver_match_device(dev, drv)) /* an OF style match first */ return 1; if (acpi_driver_match_device(dev, drv)) /* ACPI style match */ if (pdrv->id_table) /* match against the id table */ return platform_match_id(pdrv->id_table, pdev) != NULL; /* fall-back to driver name match */ return (strcmp(pdev->name, drv->name) == 0); static const struct i2c_device_id pca953x_id[] = { { "pca9535", 16 | PCA953X_TYPE | PCA_INT, }, … { "pca9555", 16 | PCA953X_TYPE | PCA_INT, }, { "pcal9555a", 16 | PCAL953X_TYPE | PCA_INT, }, … }

I2C Devices and Drivers of Galileo Board

Platform Devices and Drivers of Galileo Board