Linux Audio

Check our new training course

Loading...
v4.17
  1/*
  2 * Simple Memory-Mapped GPIOs
  3 *
  4 * Copyright (c) MontaVista Software, Inc. 2008.
  5 *
  6 * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
  7 *
  8 * This program is free software; you can redistribute  it and/or modify it
  9 * under  the terms of  the GNU General  Public License as published by the
 10 * Free Software Foundation;  either version 2 of the  License, or (at your
 11 * option) any later version.
 12 */
 13
 14#include <linux/init.h>
 15#include <linux/kernel.h>
 
 16#include <linux/spinlock.h>
 17#include <linux/types.h>
 18#include <linux/ioport.h>
 19#include <linux/io.h>
 20#include <linux/of.h>
 21#include <linux/of_gpio.h>
 22#include <linux/gpio/driver.h>
 23#include <linux/slab.h>
 24#include <asm/prom.h>
 25#include "simple_gpio.h"
 26
 27struct u8_gpio_chip {
 28	struct of_mm_gpio_chip mm_gc;
 29	spinlock_t lock;
 30
 31	/* shadowed data register to clear/set bits safely */
 32	u8 data;
 33};
 34
 
 
 
 
 
 35static u8 u8_pin2mask(unsigned int pin)
 36{
 37	return 1 << (8 - 1 - pin);
 38}
 39
 40static int u8_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 41{
 42	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 43
 44	return !!(in_8(mm_gc->regs) & u8_pin2mask(gpio));
 45}
 46
 47static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 48{
 49	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 50	struct u8_gpio_chip *u8_gc = gpiochip_get_data(gc);
 51	unsigned long flags;
 52
 53	spin_lock_irqsave(&u8_gc->lock, flags);
 54
 55	if (val)
 56		u8_gc->data |= u8_pin2mask(gpio);
 57	else
 58		u8_gc->data &= ~u8_pin2mask(gpio);
 59
 60	out_8(mm_gc->regs, u8_gc->data);
 61
 62	spin_unlock_irqrestore(&u8_gc->lock, flags);
 63}
 64
 65static int u8_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 66{
 67	return 0;
 68}
 69
 70static int u8_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 71{
 72	u8_gpio_set(gc, gpio, val);
 73	return 0;
 74}
 75
 76static void u8_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 77{
 78	struct u8_gpio_chip *u8_gc =
 79		container_of(mm_gc, struct u8_gpio_chip, mm_gc);
 80
 81	u8_gc->data = in_8(mm_gc->regs);
 82}
 83
 84static int __init u8_simple_gpiochip_add(struct device_node *np)
 85{
 86	int ret;
 87	struct u8_gpio_chip *u8_gc;
 88	struct of_mm_gpio_chip *mm_gc;
 89	struct gpio_chip *gc;
 90
 91	u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL);
 92	if (!u8_gc)
 93		return -ENOMEM;
 94
 95	spin_lock_init(&u8_gc->lock);
 96
 97	mm_gc = &u8_gc->mm_gc;
 98	gc = &mm_gc->gc;
 99
100	mm_gc->save_regs = u8_gpio_save_regs;
101	gc->ngpio = 8;
102	gc->direction_input = u8_gpio_dir_in;
103	gc->direction_output = u8_gpio_dir_out;
104	gc->get = u8_gpio_get;
105	gc->set = u8_gpio_set;
106
107	ret = of_mm_gpiochip_add_data(np, mm_gc, u8_gc);
108	if (ret)
109		goto err;
110	return 0;
111err:
112	kfree(u8_gc);
113	return ret;
114}
115
116void __init simple_gpiochip_init(const char *compatible)
117{
118	struct device_node *np;
119
120	for_each_compatible_node(np, NULL, compatible) {
121		int ret;
122		struct resource r;
123
124		ret = of_address_to_resource(np, 0, &r);
125		if (ret)
126			goto err;
127
128		switch (resource_size(&r)) {
129		case 1:
130			ret = u8_simple_gpiochip_add(np);
131			if (ret)
132				goto err;
133			break;
134		default:
135			/*
136			 * Whenever you need support for GPIO bank width > 1,
137			 * please just turn u8_ code into huge macros, and
138			 * construct needed uX_ code with it.
139			 */
140			ret = -ENOSYS;
141			goto err;
142		}
143		continue;
144err:
145		pr_err("%pOF: registration failed, status %d\n", np, ret);
 
146	}
147}
v3.1
  1/*
  2 * Simple Memory-Mapped GPIOs
  3 *
  4 * Copyright (c) MontaVista Software, Inc. 2008.
  5 *
  6 * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
  7 *
  8 * This program is free software; you can redistribute  it and/or modify it
  9 * under  the terms of  the GNU General  Public License as published by the
 10 * Free Software Foundation;  either version 2 of the  License, or (at your
 11 * option) any later version.
 12 */
 13
 14#include <linux/init.h>
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17#include <linux/spinlock.h>
 18#include <linux/types.h>
 19#include <linux/ioport.h>
 20#include <linux/io.h>
 21#include <linux/of.h>
 22#include <linux/of_gpio.h>
 23#include <linux/gpio.h>
 24#include <linux/slab.h>
 25#include <asm/prom.h>
 26#include "simple_gpio.h"
 27
 28struct u8_gpio_chip {
 29	struct of_mm_gpio_chip mm_gc;
 30	spinlock_t lock;
 31
 32	/* shadowed data register to clear/set bits safely */
 33	u8 data;
 34};
 35
 36static struct u8_gpio_chip *to_u8_gpio_chip(struct of_mm_gpio_chip *mm_gc)
 37{
 38	return container_of(mm_gc, struct u8_gpio_chip, mm_gc);
 39}
 40
 41static u8 u8_pin2mask(unsigned int pin)
 42{
 43	return 1 << (8 - 1 - pin);
 44}
 45
 46static int u8_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 47{
 48	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 49
 50	return in_8(mm_gc->regs) & u8_pin2mask(gpio);
 51}
 52
 53static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 54{
 55	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 56	struct u8_gpio_chip *u8_gc = to_u8_gpio_chip(mm_gc);
 57	unsigned long flags;
 58
 59	spin_lock_irqsave(&u8_gc->lock, flags);
 60
 61	if (val)
 62		u8_gc->data |= u8_pin2mask(gpio);
 63	else
 64		u8_gc->data &= ~u8_pin2mask(gpio);
 65
 66	out_8(mm_gc->regs, u8_gc->data);
 67
 68	spin_unlock_irqrestore(&u8_gc->lock, flags);
 69}
 70
 71static int u8_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 72{
 73	return 0;
 74}
 75
 76static int u8_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 77{
 78	u8_gpio_set(gc, gpio, val);
 79	return 0;
 80}
 81
 82static void u8_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 83{
 84	struct u8_gpio_chip *u8_gc = to_u8_gpio_chip(mm_gc);
 
 85
 86	u8_gc->data = in_8(mm_gc->regs);
 87}
 88
 89static int __init u8_simple_gpiochip_add(struct device_node *np)
 90{
 91	int ret;
 92	struct u8_gpio_chip *u8_gc;
 93	struct of_mm_gpio_chip *mm_gc;
 94	struct gpio_chip *gc;
 95
 96	u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL);
 97	if (!u8_gc)
 98		return -ENOMEM;
 99
100	spin_lock_init(&u8_gc->lock);
101
102	mm_gc = &u8_gc->mm_gc;
103	gc = &mm_gc->gc;
104
105	mm_gc->save_regs = u8_gpio_save_regs;
106	gc->ngpio = 8;
107	gc->direction_input = u8_gpio_dir_in;
108	gc->direction_output = u8_gpio_dir_out;
109	gc->get = u8_gpio_get;
110	gc->set = u8_gpio_set;
111
112	ret = of_mm_gpiochip_add(np, mm_gc);
113	if (ret)
114		goto err;
115	return 0;
116err:
117	kfree(u8_gc);
118	return ret;
119}
120
121void __init simple_gpiochip_init(const char *compatible)
122{
123	struct device_node *np;
124
125	for_each_compatible_node(np, NULL, compatible) {
126		int ret;
127		struct resource r;
128
129		ret = of_address_to_resource(np, 0, &r);
130		if (ret)
131			goto err;
132
133		switch (resource_size(&r)) {
134		case 1:
135			ret = u8_simple_gpiochip_add(np);
136			if (ret)
137				goto err;
138			break;
139		default:
140			/*
141			 * Whenever you need support for GPIO bank width > 1,
142			 * please just turn u8_ code into huge macros, and
143			 * construct needed uX_ code with it.
144			 */
145			ret = -ENOSYS;
146			goto err;
147		}
148		continue;
149err:
150		pr_err("%s: registration failed, status %d\n",
151		       np->full_name, ret);
152	}
153}