18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Coldfire generic GPIO support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (C) Copyright 2009, Steven King <sfking@fdwdc.com> 68c2ecf20Sopenharmony_ci*/ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef coldfire_gpio_h 98c2ecf20Sopenharmony_ci#define coldfire_gpio_h 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/io.h> 128c2ecf20Sopenharmony_ci#include <asm/coldfire.h> 138c2ecf20Sopenharmony_ci#include <asm/mcfsim.h> 148c2ecf20Sopenharmony_ci#include <asm/mcfgpio.h> 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * The Generic GPIO functions 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * If the gpio is a compile time constant and is one of the Coldfire gpios, 198c2ecf20Sopenharmony_ci * use the inline version, otherwise dispatch thru gpiolib. 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic inline int gpio_get_value(unsigned gpio) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) 258c2ecf20Sopenharmony_ci return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio); 268c2ecf20Sopenharmony_ci else 278c2ecf20Sopenharmony_ci return __gpio_get_value(gpio); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic inline void gpio_set_value(unsigned gpio, int value) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) { 338c2ecf20Sopenharmony_ci if (gpio < MCFGPIO_SCR_START) { 348c2ecf20Sopenharmony_ci unsigned long flags; 358c2ecf20Sopenharmony_ci MCFGPIO_PORTTYPE data; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci local_irq_save(flags); 388c2ecf20Sopenharmony_ci data = mcfgpio_read(__mcfgpio_podr(gpio)); 398c2ecf20Sopenharmony_ci if (value) 408c2ecf20Sopenharmony_ci data |= mcfgpio_bit(gpio); 418c2ecf20Sopenharmony_ci else 428c2ecf20Sopenharmony_ci data &= ~mcfgpio_bit(gpio); 438c2ecf20Sopenharmony_ci mcfgpio_write(data, __mcfgpio_podr(gpio)); 448c2ecf20Sopenharmony_ci local_irq_restore(flags); 458c2ecf20Sopenharmony_ci } else { 468c2ecf20Sopenharmony_ci if (value) 478c2ecf20Sopenharmony_ci mcfgpio_write(mcfgpio_bit(gpio), 488c2ecf20Sopenharmony_ci MCFGPIO_SETR_PORT(gpio)); 498c2ecf20Sopenharmony_ci else 508c2ecf20Sopenharmony_ci mcfgpio_write(~mcfgpio_bit(gpio), 518c2ecf20Sopenharmony_ci MCFGPIO_CLRR_PORT(gpio)); 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci } else 548c2ecf20Sopenharmony_ci __gpio_set_value(gpio, value); 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic inline int gpio_to_irq(unsigned gpio) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci#if defined(MCFGPIO_IRQ_MIN) 608c2ecf20Sopenharmony_ci if ((gpio >= MCFGPIO_IRQ_MIN) && (gpio < MCFGPIO_IRQ_MAX)) 618c2ecf20Sopenharmony_ci#else 628c2ecf20Sopenharmony_ci if (gpio < MCFGPIO_IRQ_MAX) 638c2ecf20Sopenharmony_ci#endif 648c2ecf20Sopenharmony_ci return gpio + MCFGPIO_IRQ_VECBASE; 658c2ecf20Sopenharmony_ci else 668c2ecf20Sopenharmony_ci return __gpio_to_irq(gpio); 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic inline int irq_to_gpio(unsigned irq) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci return (irq >= MCFGPIO_IRQ_VECBASE && 728c2ecf20Sopenharmony_ci irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ? 738c2ecf20Sopenharmony_ci irq - MCFGPIO_IRQ_VECBASE : -ENXIO; 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic inline int gpio_cansleep(unsigned gpio) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci#ifndef CONFIG_GPIOLIB 828c2ecf20Sopenharmony_cistatic inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci int err; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci err = gpio_request(gpio, label); 878c2ecf20Sopenharmony_ci if (err) 888c2ecf20Sopenharmony_ci return err; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci if (flags & GPIOF_DIR_IN) 918c2ecf20Sopenharmony_ci err = gpio_direction_input(gpio); 928c2ecf20Sopenharmony_ci else 938c2ecf20Sopenharmony_ci err = gpio_direction_output(gpio, 948c2ecf20Sopenharmony_ci (flags & GPIOF_INIT_HIGH) ? 1 : 0); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci if (err) 978c2ecf20Sopenharmony_ci gpio_free(gpio); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci return err; 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci#endif /* !CONFIG_GPIOLIB */ 1028c2ecf20Sopenharmony_ci#endif 103