static int set_gpiochip(void) { gpiochip = gpiochip_find(LIRC_GPIO_ID_STRING, is_right_chip); if (!gpiochip) return -ENODEV; return 0; }
static int bcm2835_spi_setup(struct spi_device *spi) { int err; struct gpio_chip *chip; /* * sanity checking the native-chipselects */ if (spi->mode & SPI_NO_CS) return 0; if (gpio_is_valid(spi->cs_gpio)) return 0; if (spi->chip_select > 1) { /* error in the case of native CS requested with CS > 1 * officially there is a CS2, but it is not documented * which GPIO is connected with that... */ dev_err(&spi->dev, "setup: only two native chip-selects are supported\n"); return -EINVAL; } /* now translate native cs to GPIO */ /* get the gpio chip for the base */ chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); if (!chip) return 0; /* and calculate the real CS */ spi->cs_gpio = chip->base + 8 - spi->chip_select; /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", spi->chip_select, spi->cs_gpio); /* set up GPIO as output and pull to the correct level */ err = gpio_direction_output(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? 0 : 1); if (err) { dev_err(&spi->dev, "could not set CS%i gpio %i as output: %i", spi->chip_select, spi->cs_gpio, err); return err; } return 0; }
static int gpio_calc_base(void) { struct gpio_chip *gpiochip; int i; /* Iterate over all possible GPIOs until we find the first GPIO chip, matching the base */ for (i = 0 ; i < ARCH_NR_GPIOS; i++){ gpiochip = gpiochip_find(&i, gpiochip_match); if (gpiochip) { /* This is the first GPIO chip, we will use it as a global base even * if there exist more gpiochips */ printk(KERN_INFO LIRC_DRIVER_NAME ": Found GPIO chip, label = %s, base = %d\n", gpiochip->label, i); return i; } } return 0; }
static struct gpio_desc *acpi_get_gpiod(char *path, int pin) { struct gpio_chip *chip; acpi_handle handle; acpi_status status; status = acpi_get_handle(NULL, path, &handle); if (ACPI_FAILURE(status)) return ERR_PTR(-ENODEV); chip = gpiochip_find(handle, acpi_gpiochip_find); if (!chip) return ERR_PTR(-ENODEV); if (pin < 0 || pin > chip->ngpio) return ERR_PTR(-EINVAL); return gpio_to_desc(chip->base + pin); }
int tilt_sensor_init(void) { int result; result = register_chrdev(64, "tilt_sensor", &tilt_sensor_fops); if (result < 0) { printk("register_chrdev() : faild.\n"); return result; } printk("register_chrdev() : successful.\n"); gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); if (!gpiochip) { printk("gpiochip_find() failed...\n"); return -ENODEV; } if (gpio_request(gpio_s1, DRIVER_NAME " ir/in")) { printk(KERN_ALERT DRIVER_NAME ": cant claim gpio pin %d\n", gpio_s1); gpio_free(gpio_s1); return -ENODEV; } if (gpio_request(gpio_s2, DRIVER_NAME " ir/in")) { printk(KERN_ALERT DRIVER_NAME ": cant claim gpio pin %d\n", gpio_s2); gpio_free(gpio_s2); return -ENODEV; } printk("gpiochip_find() successful!\n"); gpiochip->direction_input(gpiochip, gpio_s1); gpiochip->direction_input(gpiochip, gpio_s2); return 0; }
static void mx35_3ds_lcd_set_power( struct plat_lcd_data *pd, unsigned int power) { struct gpio_chip *chip; if (!gpio_is_valid(lcd_power_gpio)) { chip = gpiochip_find( "mc9s08dz60", mc9s08dz60_gpiochip_match); if (chip) { lcd_power_gpio = chip->base + GPIO_MC9S08DZ60_LCD_ENABLE; if (gpio_request(lcd_power_gpio, "lcd_power") < 0) { pr_err("error: gpio already requested!\n"); lcd_power_gpio = -ENXIO; } } else { pr_err("error: didn't find mc9s08dz60 gpio chip\n"); } } if (gpio_is_valid(lcd_power_gpio)) gpio_set_value_cansleep(lcd_power_gpio, power); }
//内核加载后的初始化函数. static int __init pi_led_init(void) { struct device *dev; int major; //自动分配主设备号 major = alloc_chrdev_region(&pi_led_devno,0,1,DRIVER_NAME); //register_chrdev 注册字符设备使系统知道有LED这个模块在. cdev_init(&pi_led_class_dev, &pi_led_dev_fops); major = cdev_add(&pi_led_class_dev,pi_led_devno,1); //注册class pi_led_class = class_create(THIS_MODULE,DRIVER_NAME); dev = device_create(pi_led_class ,NULL,pi_led_devno,NULL,DRIVER_NAME); gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); gpiochip->direction_output(gpiochip, led_pin, 1); gpiochip->set(gpiochip, led_pin, 1); msleep(500); gpiochip->set(gpiochip, led_pin, 0); interval = 500; printk("pi led init ok!\n"); return 0; }
static int init_port(void) { int i, nlow, nhigh, ret; struct device_node *node; node = lirc_rpi_dev->dev.of_node; gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); /* * Because of the lack of a setpull function, only support * pinctrl-bcm2835 if using device tree. */ if (!gpiochip && node) gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip); if (!gpiochip) { pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n"); return -ENODEV; } if (node) { struct device_node *pins_node; pins_node = of_parse_phandle(node, "pinctrl-0", 0); if (!pins_node) { printk(KERN_ERR LIRC_DRIVER_NAME ": pinctrl settings not found!\n"); ret = -EINVAL; goto exit_init_port; } read_pin_settings(pins_node); of_property_read_u32(node, "rpi,sense", &sense); read_bool_property(node, "rpi,softcarrier", &softcarrier); read_bool_property(node, "rpi,invert", &invert); read_bool_property(node, "rpi,debug", &debug); } else { for(i=0;i<INPUT_PIN_NUM;i++) { if (gpio_in_pin[i] >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) { ret = -EINVAL; printk(KERN_ERR LIRC_DRIVER_NAME ": invalid GPIO pin(s) specified!\n"); goto exit_init_port; } if (gpio_request(gpio_in_pin[i], LIRC_DRIVER_NAME " ir/in")) { printk(KERN_ALERT LIRC_DRIVER_NAME ": cant claim gpio pin %d\n", gpio_in_pin[i]); ret = -ENODEV; goto exit_gpio_free_out_pin; } bcm2708_gpio_setpull(gpiochip, gpio_in_pin[i], gpio_in_pull); gpiochip->direction_input(gpiochip, gpio_in_pin[i]); } if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { printk(KERN_ALERT LIRC_DRIVER_NAME ": cant claim gpio pin %d\n", gpio_out_pin); ret = -ENODEV; goto exit_init_port; } gpiochip->direction_output(gpiochip, gpio_out_pin, 1); } gpiochip->set(gpiochip, gpio_out_pin, invert); for (i=0; i<INPUT_PIN_NUM; i++){ irq_num[i] = gpiochip->to_irq(gpiochip, gpio_in_pin[i]); printk(KERN_INFO LIRC_DRIVER_NAME "to_irq %d gpio_num %d \n", irq_num[i], gpio_in_pin[i]); } printk(KERN_INFO LIRC_DRIVER_NAME "gpio_out %d \n",gpio_out_pin); /* if pin is high, then this must be an active low receiver. */ if (sense == -1) { /* wait 1/2 sec for the power supply */ msleep(500); /* * probe 9 times every 0.04s, collect "votes" for * active high/low */ nlow = 0; nhigh = 0; for (i = 0; i < 9; i++) { if (gpiochip->get(gpiochip, gpio_in_pin[0])) nlow++; else nhigh++; msleep(40); } sense = (nlow >= nhigh ? 1 : 0); printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active %s receiver on GPIO pin %d\n", sense ? "low" : "high", gpio_in_pin[0]); } else { printk(KERN_INFO LIRC_DRIVER_NAME ": manually using active %s receiver on GPIO pin %d\n", sense ? "low" : "high", gpio_in_pin[0]); } return 0; exit_gpio_free_out_pin: gpio_free(gpio_out_pin); exit_init_port: return ret; }
/** * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API * @np: device node to get GPIO from * @propname: property name containing gpio specifier(s) * @index: index of the GPIO * @flags: a flags pointer to fill in * * Returns GPIO number to use with Linux generic GPIO API, or one of the errno * value on the error condition. If @flags is not NULL the function also fills * in flags for the GPIO. */ int of_get_named_gpio_flags(struct device_node *np, const char *propname, int index, enum of_gpio_flags *flags) { /* Return -EPROBE_DEFER to support probe() functions to be called * later when the GPIO actually becomes available */ struct gg_data gg_data = { .flags = flags, .out_gpio = -EPROBE_DEFER }; int ret; /* .of_xlate might decide to not fill in the flags, so clear it. */ if (flags) *flags = 0; ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, &gg_data.gpiospec); if (ret) { pr_debug("%s: can't parse gpios property of node '%s[%d]'\n", __func__, np->full_name, index); return ret; } gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); of_node_put(gg_data.gpiospec.np); pr_debug("%s exited with status %d\n", __func__, gg_data.out_gpio); return gg_data.out_gpio; } EXPORT_SYMBOL(of_get_named_gpio_flags); /** * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags * @gc: pointer to the gpio_chip structure * @np: device node of the GPIO chip * @gpio_spec: gpio specifier as found in the device tree * @flags: a flags pointer to fill in * * This is simple translation function, suitable for the most 1:1 mapped * gpio chips. This function performs only one sanity check: whether gpio * is less than ngpios (that is specified in the gpio_chip). */ int of_gpio_simple_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags) { /* * We're discouraging gpio_cells < 2, since that way you'll have to * write your own xlate function (that will have to retrive the GPIO * number and the flags from a single gpio cell -- this is possible, * but not recommended). */ if (gc->of_gpio_n_cells < 2) { WARN_ON(1); return -EINVAL; } if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) return -EINVAL; if (gpiospec->args[0] >= gc->ngpio) return -EINVAL; if (flags) *flags = gpiospec->args[1]; return gpiospec->args[0]; } EXPORT_SYMBOL(of_gpio_simple_xlate); /** * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) * @np: device node of the GPIO chip * @mm_gc: pointer to the of_mm_gpio_chip allocated structure * * To use this function you should allocate and fill mm_gc with: * * 1) In the gpio_chip structure: * - all the callbacks * - of_gpio_n_cells * - of_xlate callback (optional) * * 3) In the of_mm_gpio_chip structure: * - save_regs callback (optional) * * If succeeded, this function will map bank's memory and will * do all necessary work for you. Then you'll able to use .regs * to manage GPIOs from the callbacks. */ int of_mm_gpiochip_add(struct device_node *np, struct of_mm_gpio_chip *mm_gc) { int ret = -ENOMEM; struct gpio_chip *gc = &mm_gc->gc; gc->label = kstrdup(np->full_name, GFP_KERNEL); if (!gc->label) goto err0; mm_gc->regs = of_iomap(np, 0); if (!mm_gc->regs) goto err1; gc->base = -1; if (mm_gc->save_regs) mm_gc->save_regs(mm_gc); mm_gc->gc.of_node = np; ret = gpiochip_add(gc); if (ret) goto err2; return 0; err2: iounmap(mm_gc->regs); err1: kfree(gc->label); err0: pr_err("%s: GPIO chip registration failed with status %d\n", np->full_name, ret); return ret; }
static struct gpio_chip *of_find_gpiochip_by_xlate( struct of_phandle_args *gpiospec) { return gpiochip_find(gpiospec, of_gpiochip_match_node_and_xlate); }
struct gpio_chip *of_node_to_gpiochip(struct device_node *np) { return gpiochip_find(np, of_gpiochip_is_match); }
/** * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API * @np: device node to get GPIO from * @propname: property name containing gpio specifier(s) * @index: index of the GPIO * @flags: a flags pointer to fill in * * Returns GPIO number to use with Linux generic GPIO API, or one of the errno * value on the error condition. If @flags is not NULL the function also fills * in flags for the GPIO. */ int of_get_named_gpio_flags(struct device_node *np, const char *propname, int index, enum of_gpio_flags *flags) { /* Return -EPROBE_DEFER to support probe() functions to be called * later when the GPIO actually becomes available */ struct gg_data gg_data = { .flags = flags, .out_gpio = -EPROBE_DEFER }; int ret; /* .of_xlate might decide to not fill in the flags, so clear it. */ if (flags) *flags = 0; ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, &gg_data.gpiospec); if (ret) { pr_debug("%s: can't parse gpios property\n", __func__); return ret; } gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); of_node_put(gg_data.gpiospec.np); pr_debug("%s exited with status %d\n", __func__, gg_data.out_gpio); return gg_data.out_gpio; } EXPORT_SYMBOL(of_get_named_gpio_flags); /** * of_gpio_named_count - Count GPIOs for a device * @np: device node to count GPIOs for * @propname: property name containing gpio specifier(s) * * The function returns the count of GPIOs specified for a node. * * Note that the empty GPIO specifiers counts too. For example, * * gpios = <0 * &pio1 1 2 * 0 * &pio2 3 4>; * * defines four GPIOs (so this function will return 4), two of which * are not specified. */ unsigned int of_gpio_named_count(struct device_node *np, const char* propname) { unsigned int cnt = 0; do { int ret; ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", cnt, NULL); /* A hole in the gpios = <> counts anyway. */ if (ret < 0 && ret != -EEXIST) break; } while (++cnt); return cnt; }
__init int engine_init(void){ int ret; printk (KERN_INFO ENGINE_DRIVER_NAME ": init\n") ; gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); if (!gpiochip) return -ENODEV; if (gpio_request(A1_PIN, ENGINE_DRIVER_NAME "A1_PIN")) { printk(KERN_ALERT ENGINE_DRIVER_NAME ": cant claim gpio pin %d\n", A1_PIN); ret = -ENODEV; goto exitA1; } if (gpio_request(A2_PIN, ENGINE_DRIVER_NAME "A2_PIN")) { printk(KERN_ALERT ENGINE_DRIVER_NAME ": cant claim gpio pin %d\n", A2_PIN); ret = -ENODEV; goto exitA2; } if (gpio_request(B1_PIN, ENGINE_DRIVER_NAME "B1_PIN")) { printk(KERN_ALERT ENGINE_DRIVER_NAME ": cant claim gpio pin %d\n", B1_PIN); ret = -ENODEV; goto exitB1; } if (gpio_request(B2_PIN, ENGINE_DRIVER_NAME "B2_PIN")) { printk(KERN_ALERT ENGINE_DRIVER_NAME ": cant claim gpio pin %d\n", B2_PIN); ret = -ENODEV; goto exitB2; } printk(KERN_INFO ENGINE_DRIVER_NAME ": got all pins.\n"); gpiochip->direction_output(gpiochip, A1_PIN, 1); gpiochip->set(gpiochip, A1_PIN, 1); gpiochip->direction_output(gpiochip, A2_PIN, 1); gpiochip->set(gpiochip, A2_PIN, 1); gpiochip->direction_output(gpiochip, B1_PIN, 1); gpiochip->set(gpiochip, B1_PIN, 1); gpiochip->direction_output(gpiochip, B1_PIN, 1); gpiochip->set(gpiochip, B2_PIN, 1); alloc_chrdev_region(&deviceMajMin, 0, 1, DEVICE_NAME); printk (KERN_INFO ENGINE_DRIVER_NAME ": major: %d\n", MAJOR(deviceMajMin)); class = class_create(THIS_MODULE, DEVICE_NAME); cdev_init(&cdev, &fops); cdev.owner = THIS_MODULE; cdev_add(&cdev, deviceMajMin, 1); device_create(class, NULL, deviceMajMin, NULL, DEVICE_NAME); hrtimer_init(&step_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); step_timer.function = &hrtimer_routine; run_timer(steptime); return 0; exitB2: gpio_free(B1_PIN); exitB1: gpio_free(A2_PIN); exitA2: gpio_free(A1_PIN); exitA1: return ret; }