Linux Audio

Check our new training course

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