Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:44

0001 /*  gpio.c
0002  *
0003  *  GPIO driver for the Milkymist One board
0004  *
0005  *  The license and distribution terms for this file may be
0006  *  found in the file LICENSE in this distribution or at
0007  *  http://www.rtems.org/license/LICENSE.
0008  *
0009  *  COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
0010  *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
0011  *  Telecom SudParis
0012  */
0013 
0014 #define RTEMS_STATUS_CHECKS_USE_PRINTK
0015 
0016 #include <stdlib.h>
0017 #include <stdio.h>
0018 #include <errno.h>
0019 #include <sys/types.h>
0020 #include <rtems.h>
0021 #include <rtems/status-checks.h>
0022 #include <bsp.h>
0023 #include <rtems/libio.h>
0024 #include "../include/system_conf.h"
0025 #include <bsp/milkymist_gpio.h>
0026 
0027 struct milkymist_gpio {
0028   char *name;
0029   unsigned int mask;
0030   bool readonly;
0031 };
0032 
0033 static const struct milkymist_gpio gpio[] = {
0034   {
0035     .name = "/dev/led1",
0036     .mask = GPIO_LED1,
0037     .readonly = false
0038   },
0039   {
0040     .name = "/dev/led2",
0041     .mask = GPIO_LED2,
0042     .readonly = false
0043   },
0044 };
0045 
0046 rtems_device_driver gpio_initialize(
0047   rtems_device_major_number major,
0048   rtems_device_minor_number minor,
0049   void *arg
0050 )
0051 {
0052   rtems_status_code sc;
0053   int i;
0054 
0055   for (i=0;i<sizeof(gpio)/sizeof(struct milkymist_gpio);i++) {
0056     sc = rtems_io_register_name(gpio[i].name, major, i);
0057     RTEMS_CHECK_SC(sc, "create GPIO device");
0058   }
0059 
0060   return RTEMS_SUCCESSFUL;
0061 }
0062 
0063 rtems_device_driver gpio_read(
0064   rtems_device_major_number major,
0065   rtems_device_minor_number minor,
0066   void *arg
0067 )
0068 {
0069   unsigned int data;
0070 
0071   rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
0072 
0073   if (rw_args->offset > 0) {
0074     rw_args->bytes_moved = 0;
0075     return RTEMS_SUCCESSFUL;
0076   }
0077 
0078   rw_args->bytes_moved = 1;
0079 
0080   if (gpio[minor].readonly)
0081     data = MM_READ(MM_GPIO_IN);
0082   else
0083     data = MM_READ(MM_GPIO_OUT);
0084 
0085   if (data & gpio[minor].mask)
0086     *(uint8_t *)rw_args->buffer = '1';
0087   else
0088     *(uint8_t *)rw_args->buffer = '0';
0089 
0090   return RTEMS_SUCCESSFUL;
0091 }
0092 
0093 rtems_device_driver gpio_write(
0094   rtems_device_major_number  major,
0095   rtems_device_minor_number  minor,
0096   void *arg
0097 )
0098 {
0099   rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
0100 
0101   if (gpio[minor].readonly) {
0102     rw_args->bytes_moved = 0;
0103     return RTEMS_UNSATISFIED;
0104   }
0105 
0106   if (rw_args->offset > 0) {
0107     rw_args->bytes_moved = 0;
0108     return RTEMS_SUCCESSFUL;
0109   }
0110 
0111   rw_args->bytes_moved = 1;
0112 
0113   if (*(uint8_t *)rw_args->buffer == '1')
0114     MM_WRITE(MM_GPIO_OUT, MM_READ(MM_GPIO_OUT)|gpio[minor].mask);
0115   else
0116     MM_WRITE(MM_GPIO_OUT, MM_READ(MM_GPIO_OUT) & ~gpio[minor].mask);
0117 
0118   return RTEMS_SUCCESSFUL;
0119 }