added checks to pin configuration
This commit is contained in:
parent
15a4f817f2
commit
060ffddcf1
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
obj-m = lcd.o
|
obj-m = lcd.o
|
||||||
lcd-y = src/lcd.o src/io.o
|
lcd-y = src/lcd.o src/io.o src/checks.o
|
||||||
|
|
||||||
KVERSION = $(shell uname -r)
|
KVERSION = $(shell uname -r)
|
||||||
|
|
||||||
|
|
37
src/checks.c
Normal file
37
src/checks.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#include "checks.h"
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include "lcd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define LCD_MIN_GPIO 2
|
||||||
|
#define LCD_MAX_GPIO 27
|
||||||
|
|
||||||
|
static int sub_pin = LCD_MIN_GPIO;
|
||||||
|
|
||||||
|
int lcd_is_valid_gpio(int pin)
|
||||||
|
{
|
||||||
|
return (LCD_MIN_GPIO <= pin && pin <= LCD_MAX_GPIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_assign_gpio(int pin)
|
||||||
|
{
|
||||||
|
if(lcd_is_valid_gpio(pin))
|
||||||
|
return pin;
|
||||||
|
|
||||||
|
|
||||||
|
printk(KERN_WARNING "%s: GPIO pin %d is invalid. Using %d instead\n", THIS_MODULE->name, pin, sub_pin);
|
||||||
|
return sub_pin++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_check_duplicates(const int* used_pins)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for(i = 0; i < 7; i++)
|
||||||
|
for(j = i + 1; j < 8; j++)
|
||||||
|
if(used_pins[i] == used_pins[j])
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
11
src/checks.h
Normal file
11
src/checks.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef _LCD_CHECKS_H
|
||||||
|
#define _LCD_CHECKS_H
|
||||||
|
|
||||||
|
struct lcd_gpio_config;
|
||||||
|
|
||||||
|
int lcd_is_valid_gpio(int pin);
|
||||||
|
int lcd_assign_gpio(int pin);
|
||||||
|
|
||||||
|
int lcd_check_duplicates(const int* config);
|
||||||
|
|
||||||
|
#endif
|
41
src/lcd.c
41
src/lcd.c
|
@ -5,6 +5,7 @@
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
|
#include "checks.h"
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
@ -85,7 +86,10 @@ static int __init lcd_init_module(void)
|
||||||
|
|
||||||
result = lcd_init_gpio();
|
result = lcd_init_gpio();
|
||||||
if(result < 0)
|
if(result < 0)
|
||||||
|
{
|
||||||
|
printk(KERN_ERR "%s: Failed to configure GPIO pins\n", THIS_MODULE->name);
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "%s: Module loaded!\n", THIS_MODULE->name);
|
printk(KERN_INFO "%s: Module loaded!\n", THIS_MODULE->name);
|
||||||
return result;
|
return result;
|
||||||
|
@ -120,26 +124,41 @@ static int __init lcd_init_cdev(void)
|
||||||
|
|
||||||
static int __init lcd_init_gpio(void)
|
static int __init lcd_init_gpio(void)
|
||||||
{
|
{
|
||||||
lcd_validate_gpio();
|
int result, i;
|
||||||
|
|
||||||
|
result = lcd_validate_gpio();
|
||||||
|
|
||||||
|
if(result < 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
for(i = 0; i < 8; i++)
|
||||||
|
gpio_direction_output(lcddev.used_pins[i], 0);
|
||||||
|
|
||||||
// gpio_direction_output(lcddev.gpio, 0);
|
return result;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init lcd_validate_gpio(void)
|
static int __init lcd_validate_gpio(void)
|
||||||
{
|
{
|
||||||
|
int result = 0;
|
||||||
struct lcd_gpio_config* config = &lcddev.config;
|
struct lcd_gpio_config* config = &lcddev.config;
|
||||||
|
lcddev.used_pins = (int*)config;
|
||||||
|
|
||||||
config->power = pin_power;
|
config->power = lcd_assign_gpio(pin_power);
|
||||||
config->rs = pin_rs;
|
config->rs = lcd_assign_gpio(pin_rs);
|
||||||
config->rw = pin_rw;
|
config->rw = lcd_assign_gpio(pin_rw);
|
||||||
config->enable = pin_enable;
|
config->enable = lcd_assign_gpio(pin_enable);
|
||||||
|
|
||||||
memcpy(config->data, pin_data, 4 * sizeof(int));
|
config->data[0] = lcd_assign_gpio(pin_data[0]);
|
||||||
|
config->data[1] = lcd_assign_gpio(pin_data[1]);
|
||||||
|
config->data[2] = lcd_assign_gpio(pin_data[2]);
|
||||||
|
config->data[3] = lcd_assign_gpio(pin_data[3]);
|
||||||
|
|
||||||
// TODO: Check if pin configuration is valid
|
result = lcd_check_duplicates(lcddev.used_pins);
|
||||||
// - no duplicate pins?
|
if(result < 0)
|
||||||
// - all pin numbers in range?
|
{
|
||||||
|
printk(KERN_ERR "%s: Invalid pin configuration (duplicate pin usage)\n", THIS_MODULE->name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/cdev.h>
|
#include <linux/cdev.h>
|
||||||
|
#include <linux/semaphore.h>
|
||||||
|
|
||||||
#define LCD_MAJOR 0
|
#define LCD_MAJOR 0
|
||||||
#define LCD_MINOR 0
|
#define LCD_MINOR 0
|
||||||
|
@ -18,7 +19,7 @@ struct lcd_gpio_config
|
||||||
int power;
|
int power;
|
||||||
int rs, rw, enable;
|
int rs, rw, enable;
|
||||||
int data[4];
|
int data[4];
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct lcd_dev
|
struct lcd_dev
|
||||||
{
|
{
|
||||||
|
@ -26,6 +27,7 @@ struct lcd_dev
|
||||||
struct cdev dev;
|
struct cdev dev;
|
||||||
struct semaphore sem;
|
struct semaphore sem;
|
||||||
struct lcd_gpio_config config;
|
struct lcd_gpio_config config;
|
||||||
|
int* used_pins;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in a new issue