Linux Audio

Check our new training course

Linux kernel drivers training

May 6-19, 2025
Register
Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Coldfire generic GPIO support.
  4 *
  5 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
 
 
 
 
 
 
 
 
 
  6 */
  7
  8#include <linux/kernel.h>
  9#include <linux/module.h>
 10#include <linux/init.h>
 11#include <linux/device.h>
 12#include <linux/gpio/driver.h>
 13
 14#include <linux/io.h>
 15#include <asm/coldfire.h>
 16#include <asm/mcfsim.h>
 17#include <asm/mcfgpio.h>
 18
 19int __mcfgpio_get_value(unsigned gpio)
 20{
 21	return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
 22}
 23EXPORT_SYMBOL(__mcfgpio_get_value);
 24
 25void __mcfgpio_set_value(unsigned gpio, int value)
 26{
 27	if (gpio < MCFGPIO_SCR_START) {
 28		unsigned long flags;
 29		MCFGPIO_PORTTYPE data;
 30
 31		local_irq_save(flags);
 32		data = mcfgpio_read(__mcfgpio_podr(gpio));
 33		if (value)
 34			data |= mcfgpio_bit(gpio);
 35		else
 36			data &= ~mcfgpio_bit(gpio);
 37		mcfgpio_write(data, __mcfgpio_podr(gpio));
 38		local_irq_restore(flags);
 39	} else {
 40		if (value)
 41			mcfgpio_write(mcfgpio_bit(gpio),
 42					MCFGPIO_SETR_PORT(gpio));
 43		else
 44			mcfgpio_write(~mcfgpio_bit(gpio),
 45					MCFGPIO_CLRR_PORT(gpio));
 46	}
 47}
 48EXPORT_SYMBOL(__mcfgpio_set_value);
 49
 50int __mcfgpio_direction_input(unsigned gpio)
 51{
 52	unsigned long flags;
 53	MCFGPIO_PORTTYPE dir;
 54
 55	local_irq_save(flags);
 56	dir = mcfgpio_read(__mcfgpio_pddr(gpio));
 57	dir &= ~mcfgpio_bit(gpio);
 58	mcfgpio_write(dir, __mcfgpio_pddr(gpio));
 59	local_irq_restore(flags);
 60
 61	return 0;
 62}
 63EXPORT_SYMBOL(__mcfgpio_direction_input);
 64
 65int __mcfgpio_direction_output(unsigned gpio, int value)
 66{
 67	unsigned long flags;
 68	MCFGPIO_PORTTYPE data;
 69
 70	local_irq_save(flags);
 71	data = mcfgpio_read(__mcfgpio_pddr(gpio));
 72	data |= mcfgpio_bit(gpio);
 73	mcfgpio_write(data, __mcfgpio_pddr(gpio));
 74
 75	/* now set the data to output */
 76	if (gpio < MCFGPIO_SCR_START) {
 77		data = mcfgpio_read(__mcfgpio_podr(gpio));
 78		if (value)
 79			data |= mcfgpio_bit(gpio);
 80		else
 81			data &= ~mcfgpio_bit(gpio);
 82		mcfgpio_write(data, __mcfgpio_podr(gpio));
 83	} else {
 84		 if (value)
 85			mcfgpio_write(mcfgpio_bit(gpio),
 86					MCFGPIO_SETR_PORT(gpio));
 87		 else
 88			 mcfgpio_write(~mcfgpio_bit(gpio),
 89					 MCFGPIO_CLRR_PORT(gpio));
 90	}
 91	local_irq_restore(flags);
 92	return 0;
 93}
 94EXPORT_SYMBOL(__mcfgpio_direction_output);
 95
 96int __mcfgpio_request(unsigned gpio)
 97{
 98	return 0;
 99}
100EXPORT_SYMBOL(__mcfgpio_request);
101
102void __mcfgpio_free(unsigned gpio)
103{
104	__mcfgpio_direction_input(gpio);
105}
106EXPORT_SYMBOL(__mcfgpio_free);
107
108#ifdef CONFIG_GPIOLIB
109
110static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
111{
112	return __mcfgpio_direction_input(offset);
113}
114
115static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
116{
117	return !!__mcfgpio_get_value(offset);
118}
119
120static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
121				    int value)
122{
123	return __mcfgpio_direction_output(offset, value);
124}
125
126static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
127			      int value)
128{
129	__mcfgpio_set_value(offset, value);
130}
131
132static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
133{
134	return __mcfgpio_request(offset);
135}
136
137static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
138{
139	__mcfgpio_free(offset);
140}
141
142static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
143{
144#if defined(MCFGPIO_IRQ_MIN)
145	if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
146#else
147	if (offset < MCFGPIO_IRQ_MAX)
148#endif
149		return MCFGPIO_IRQ_VECBASE + offset;
150	else
151		return -EINVAL;
152}
153
154static struct gpio_chip mcfgpio_chip = {
155	.label			= "mcfgpio",
156	.request		= mcfgpio_request,
157	.free			= mcfgpio_free,
158	.direction_input	= mcfgpio_direction_input,
159	.direction_output	= mcfgpio_direction_output,
160	.get			= mcfgpio_get_value,
161	.set			= mcfgpio_set_value,
162	.to_irq			= mcfgpio_to_irq,
163	.base			= 0,
164	.ngpio			= MCFGPIO_PIN_MAX,
165};
166
167static int __init mcfgpio_sysinit(void)
168{
169	return gpiochip_add_data(&mcfgpio_chip, NULL);
170}
171
172core_initcall(mcfgpio_sysinit);
173#endif
v4.6
 
  1/*
  2 * Coldfire generic GPIO support.
  3 *
  4 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
  5 *
  6 * This program is free software; you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License as published by
  8 * the Free Software Foundation; version 2 of the License.
  9 *
 10 * This program is distributed in the hope that it will be useful,
 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13 * GNU General Public License for more details.
 14 */
 15
 16#include <linux/kernel.h>
 17#include <linux/module.h>
 18#include <linux/init.h>
 19#include <linux/device.h>
 
 20
 21#include <linux/io.h>
 22#include <asm/coldfire.h>
 23#include <asm/mcfsim.h>
 24#include <asm/mcfgpio.h>
 25
 26int __mcfgpio_get_value(unsigned gpio)
 27{
 28	return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
 29}
 30EXPORT_SYMBOL(__mcfgpio_get_value);
 31
 32void __mcfgpio_set_value(unsigned gpio, int value)
 33{
 34	if (gpio < MCFGPIO_SCR_START) {
 35		unsigned long flags;
 36		MCFGPIO_PORTTYPE data;
 37
 38		local_irq_save(flags);
 39		data = mcfgpio_read(__mcfgpio_podr(gpio));
 40		if (value)
 41			data |= mcfgpio_bit(gpio);
 42		else
 43			data &= ~mcfgpio_bit(gpio);
 44		mcfgpio_write(data, __mcfgpio_podr(gpio));
 45		local_irq_restore(flags);
 46	} else {
 47		if (value)
 48			mcfgpio_write(mcfgpio_bit(gpio),
 49					MCFGPIO_SETR_PORT(gpio));
 50		else
 51			mcfgpio_write(~mcfgpio_bit(gpio),
 52					MCFGPIO_CLRR_PORT(gpio));
 53	}
 54}
 55EXPORT_SYMBOL(__mcfgpio_set_value);
 56
 57int __mcfgpio_direction_input(unsigned gpio)
 58{
 59	unsigned long flags;
 60	MCFGPIO_PORTTYPE dir;
 61
 62	local_irq_save(flags);
 63	dir = mcfgpio_read(__mcfgpio_pddr(gpio));
 64	dir &= ~mcfgpio_bit(gpio);
 65	mcfgpio_write(dir, __mcfgpio_pddr(gpio));
 66	local_irq_restore(flags);
 67
 68	return 0;
 69}
 70EXPORT_SYMBOL(__mcfgpio_direction_input);
 71
 72int __mcfgpio_direction_output(unsigned gpio, int value)
 73{
 74	unsigned long flags;
 75	MCFGPIO_PORTTYPE data;
 76
 77	local_irq_save(flags);
 78	data = mcfgpio_read(__mcfgpio_pddr(gpio));
 79	data |= mcfgpio_bit(gpio);
 80	mcfgpio_write(data, __mcfgpio_pddr(gpio));
 81
 82	/* now set the data to output */
 83	if (gpio < MCFGPIO_SCR_START) {
 84		data = mcfgpio_read(__mcfgpio_podr(gpio));
 85		if (value)
 86			data |= mcfgpio_bit(gpio);
 87		else
 88			data &= ~mcfgpio_bit(gpio);
 89		mcfgpio_write(data, __mcfgpio_podr(gpio));
 90	} else {
 91		 if (value)
 92			mcfgpio_write(mcfgpio_bit(gpio),
 93					MCFGPIO_SETR_PORT(gpio));
 94		 else
 95			 mcfgpio_write(~mcfgpio_bit(gpio),
 96					 MCFGPIO_CLRR_PORT(gpio));
 97	}
 98	local_irq_restore(flags);
 99	return 0;
100}
101EXPORT_SYMBOL(__mcfgpio_direction_output);
102
103int __mcfgpio_request(unsigned gpio)
104{
105	return 0;
106}
107EXPORT_SYMBOL(__mcfgpio_request);
108
109void __mcfgpio_free(unsigned gpio)
110{
111	__mcfgpio_direction_input(gpio);
112}
113EXPORT_SYMBOL(__mcfgpio_free);
114
115#ifdef CONFIG_GPIOLIB
116
117static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
118{
119	return __mcfgpio_direction_input(offset);
120}
121
122static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
123{
124	return !!__mcfgpio_get_value(offset);
125}
126
127static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
128				    int value)
129{
130	return __mcfgpio_direction_output(offset, value);
131}
132
133static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
134			      int value)
135{
136	__mcfgpio_set_value(offset, value);
137}
138
139static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
140{
141	return __mcfgpio_request(offset);
142}
143
144static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
145{
146	__mcfgpio_free(offset);
147}
148
149static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
150{
151#if defined(MCFGPIO_IRQ_MIN)
152	if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
153#else
154	if (offset < MCFGPIO_IRQ_MAX)
155#endif
156		return MCFGPIO_IRQ_VECBASE + offset;
157	else
158		return -EINVAL;
159}
160
161static struct gpio_chip mcfgpio_chip = {
162	.label			= "mcfgpio",
163	.request		= mcfgpio_request,
164	.free			= mcfgpio_free,
165	.direction_input	= mcfgpio_direction_input,
166	.direction_output	= mcfgpio_direction_output,
167	.get			= mcfgpio_get_value,
168	.set			= mcfgpio_set_value,
169	.to_irq			= mcfgpio_to_irq,
170	.base			= 0,
171	.ngpio			= MCFGPIO_PIN_MAX,
172};
173
174static int __init mcfgpio_sysinit(void)
175{
176	return gpiochip_add_data(&mcfgpio_chip, NULL);
177}
178
179core_initcall(mcfgpio_sysinit);
180#endif