linux lan9252 driver source cleanup

Change to misc driver
Change space to tab
Removing unnecessary functions
pull/43/head
xoduddk123 2018-04-13 12:22:47 +09:00
parent 4bf6be795b
commit 4e7f341298
3 changed files with 169 additions and 233 deletions

View File

@ -7,7 +7,7 @@ project (SOES)
set (SOES_VERSION_MAJOR 2) set (SOES_VERSION_MAJOR 2)
set (SOES_VERSION_MINOR 1) set (SOES_VERSION_MINOR 1)
set (SOES_VERSION_PATCH 3) set (SOES_VERSION_PATCH 4)
# Generate version numbers # Generate version numbers
configure_file ( configure_file (

View File

@ -1,184 +1,160 @@
/*
Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/
00001909A.pdf
*/
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/miscdevice.h>
/*
Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/
00001909A.pdf
*/
#define LAN9252_MAGIC 'l' //8bit=0~0xff 'l'an9252 #define LAN9252_MAGIC 'l' //8bit=0~0xff 'l'an9252
#define TEST _IO(LAN9252_MAGIC, 0) #define TEST _IO(LAN9252_MAGIC, 0)
#define LAN9252_LOCK mutex_lock(&lan9252_mutex); #define LAN9252_LOCK mutex_lock(&lan9252_mutex);
#define LAN9252_UNLOCK mutex_unlock(&lan9252_mutex); #define LAN9252_UNLOCK mutex_unlock(&lan9252_mutex);
#define DEVICE_NAME "lan9252" #define DEVICE_NAME "lan9252"
#define LAN9252_MAJOR 153
/* spi command */
#define FAST_READ 0x0B #define FAST_READ 0x0B
#define FAST_READ_DUMMY 1 #define FAST_READ_DUMMY 1
struct mutex lock; struct mutex lock;
static DEFINE_MUTEX(lan9252_mutex); static DEFINE_MUTEX(lan9252_mutex);
dev_t id; static struct spi_device *lan9252;
static struct device *dev;
static struct class *lan9252_class;
static struct spi_device *lan9252_devices;
static int lan9252_ethercat_probe(struct spi_device *spi); static int lan9252_ethercat_probe(struct spi_device *spi);
static int lan9252_ethercat_remove(struct spi_device *spi); static int lan9252_ethercat_remove(struct spi_device *spi);
static int lan9252_open(struct inode *inode, struct file *filp) static loff_t lan9252_llseek(struct file *file, loff_t address, int whence)
{ {
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__); int ret;
return 0;
}
static int lan9252_release(struct inode *inode, struct file *filp) LAN9252_LOCK;
{
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
return 0;
}
static loff_t lan9252_llseek(struct file *file, loff_t address, file->f_pos = address;
int whence) ret = file->f_pos;
{
int status;
LAN9252_LOCK; LAN9252_UNLOCK;
file->f_pos = address; return ret;
status = file->f_pos;
LAN9252_UNLOCK;
return status;
} }
static int * lan9252_reg_addr_make(int address) static int * lan9252_reg_addr_make(int address)
{ {
int temp;
int temp; static int lan9252_reg_addr[2];
static int lan9252_reg_addr[2];
#ifdef DEBUG #ifdef DEBUG
int i; int i;
#endif #endif
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__); temp = address & 0xff00;
lan9252_reg_addr[0] = temp >> 8;
temp = address & 0xff00; temp = address & 0x00ff;
lan9252_reg_addr[0] = temp >> 8; lan9252_reg_addr[1] = temp;
temp = address & 0x00ff;
lan9252_reg_addr[1] = temp;
#ifdef DEBUG #ifdef DEBUG
for (i=0; i<2; i++) for (i=0; i<2; i++)
dev_dbg(&lan9252_devices->dev, "%s() lan9252_reg_addr[%d] = 0x%x\n", dev_dbg(&lan9252->dev, "%s() lan9252_reg_addr[%d] = 0x%x\n",
__FUNCTION__, i, lan9252_reg_addr[i]); __FUNCTION__, i, lan9252_reg_addr[i]);
#endif #endif
return lan9252_reg_addr; return lan9252_reg_addr;
} }
/* /*
int lan9252_test(void); int lan9252_test(void);
Description : Check the connection status of LAN9252 Description : Check the connection status of LAN9252
Retrun Value Retrun Value
0 : success 0 : success
other : fail other : fail
Register Type : SYSTEM CONTROL AND STATUS REGISTERS Register Type : SYSTEM CONTROL AND STATUS REGISTERS
Register Name(SYMBOL) : BYTE ORDER TEST REGISTER(BYTE_TEST) Register Name(SYMBOL) : BYTE ORDER TEST REGISTER(BYTE_TEST)
Offset : 0x0064 Offset : 0x0064
Size : 32bit Size : 32bit
Default : 0x87654321 Default : 0x87654321
Datasheet description : Chip-level reset/configuration Datasheet description : Chip-level reset/configuration
completion can be determined by first completion can be determined by first
polling the polling the
Byte Order Test Register(BYTE_TEST). Byte Order Test Register(BYTE_TEST).
*/ */
static int lan9252_test(void) static int lan9252_test(void)
{ {
u8 command[4]; u8 command[4];
u8 test_buffer[4]; u8 test_buffer[4];
int status=0; int ret=0;
#ifdef DEBUG #ifdef DEBUG
int i; int i;
#endif #endif
command[0]=FAST_READ; command[0]=FAST_READ;
command[1]=0x00; command[1]=0x00;
command[2]=0x64; command[2]=0x64;
command[3]=FAST_READ_DUMMY; command[3]=FAST_READ_DUMMY;
ret = spi_write_then_read(lan9252, &command, sizeof(command),
test_buffer, sizeof(test_buffer));
if (ret < 0 ) {
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
"ret=%d\n", __FUNCTION__, ret);
return -1;
}
status = spi_write_then_read(lan9252_devices, &command, ret = spi_write_then_read(lan9252, &command, sizeof(command),
sizeof(command), test_buffer, sizeof(test_buffer)); test_buffer, sizeof(test_buffer));
if (status < 0 ) { if (ret < 0) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read " dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
" failed status=%d\n", __FUNCTION__, status); "ret=%d\n", __FUNCTION__, ret);
return -1; return -1;
} }
status = spi_write_then_read(lan9252_devices, &command,
sizeof(command), test_buffer, sizeof(test_buffer));
if (status < 0 ) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
" failed status=%d\n", __FUNCTION__, status);
return -1;
}
#ifdef DEBUG #ifdef DEBUG
for (i=0; i<sizeof(test_buffer); i++) for (i=0; i<sizeof(test_buffer); i++)
dev_dbg(&lan9252_devices->dev, "%s() test_buffer[%d] = 0x%x\n", dev_dbg(&lan9252->dev, "%s() test_buffer[%d] = 0x%x\n",
__FUNCTION__, i, test_buffer[i]); __FUNCTION__, i, test_buffer[i]);
#endif #endif
if (test_buffer[0]==0x21 && test_buffer[1]==0x43 && if (test_buffer[0]==0x21 && test_buffer[1]==0x43 &&
test_buffer[2]==0x65 && test_buffer[3]==0x87) test_buffer[2]==0x65 && test_buffer[3]==0x87)
return 0; return 0;
else else
return -1; return -1;
} }
static ssize_t lan9252_read( static ssize_t lan9252_read(struct file *file, char *buffer,
struct file *file, char *buffer, size_t read_buffer_size, loff_t *f_pos)
size_t read_buffer_size, loff_t *f_pos)
{ {
u8 command[4]; u8 command[4];
u8 *read_buffer; u8 *read_buffer;
int status=0; int ret = 0;
int *lan9252_reg_read_addr; int *lan9252_reg_read_addr;
#ifdef DEBUG #ifdef DEBUG
int i; int i;
#endif #endif
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__); LAN9252_LOCK;
LAN9252_LOCK;
if (read_buffer_size <= 0) { if (read_buffer_size <= 0) {
dev_err(&lan9252_devices->dev, "read_buffer_size(%d) <= 0 \n", dev_err(&lan9252->dev, "read_buffer_size(%d) <= 0 \n",
read_buffer_size); read_buffer_size);
goto out; goto out;
} else { } else {
dev_dbg(&lan9252_devices->dev, "read_buffer_size = %d\n", dev_dbg(&lan9252->dev, "read_buffer_size = %d\n",
read_buffer_size); read_buffer_size);
} }
read_buffer= (u8 *)kmalloc((read_buffer_size) * read_buffer= (u8 *)kmalloc((read_buffer_size) * sizeof(u32),
sizeof(u32), GFP_KERNEL | GFP_DMA); GFP_KERNEL | GFP_DMA);
if (!read_buffer) { if (!read_buffer) {
dev_err(&lan9252_devices->dev, "read_buffer kmalloc error\n"); dev_err(&lan9252->dev, "write read_buffer kmalloc error\n");
status = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
memset(read_buffer, 0, (read_buffer_size) * sizeof(u8)); memset(read_buffer, 0, (read_buffer_size) * sizeof(u8));
lan9252_reg_read_addr = lan9252_reg_addr_make(file->f_pos); lan9252_reg_read_addr = lan9252_reg_addr_make(file->f_pos);
command[0] = FAST_READ; command[0] = FAST_READ;
@ -188,94 +164,88 @@ static ssize_t lan9252_read(
#ifdef DEBUG #ifdef DEBUG
for (i=0; i<4; i++) for (i=0; i<4; i++)
dev_dbg(&lan9252_devices->dev, "%s() command[%d] = 0x%x\n", dev_dbg(&lan9252->dev, "%s() command[%d] = 0x%x\n",
__FUNCTION__, i, command[i]); __FUNCTION__, i, command[i]);
#endif #endif
status = spi_write_then_read(lan9252_devices, &command, ret = spi_write_then_read(lan9252, &command, sizeof(command),
sizeof(command), read_buffer,read_buffer_size); read_buffer,read_buffer_size);
if (status < 0 ) { if (ret < 0) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read " dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
"failed status=%d\n", __FUNCTION__, status); "ret=%d\n", __FUNCTION__, ret);
goto kfree_read_buffer; goto kfree_read_buffer;
} }
#ifdef DEBUG #ifdef DEBUG
for (i=0; i<read_buffer_size; i++) for (i=0; i<read_buffer_size; i++)
dev_dbg(&lan9252_devices->dev, "%s() read_buffer[%d] = 0x%x\n", dev_dbg(&lan9252->dev, "%s() read_buffer[%d] = 0x%x\n",
__FUNCTION__, i, read_buffer[i]); __FUNCTION__, i, read_buffer[i]);
#endif #endif
if (copy_to_user(buffer, read_buffer, read_buffer_size)) { if (copy_to_user(buffer, read_buffer, read_buffer_size)) {
dev_err(&lan9252_devices->dev, "%s() copy_to_user failed\n", dev_err(&lan9252->dev, "%s() copy_to_user failed\n",
__FUNCTION__); __FUNCTION__);
status = -EFAULT; ret = -EFAULT;
goto kfree_read_buffer; goto kfree_read_buffer;
} }
status = read_buffer_size; ret = read_buffer_size;
kfree_read_buffer: kfree_read_buffer:
kfree(read_buffer); kfree(read_buffer);
out: out:
LAN9252_UNLOCK; LAN9252_UNLOCK;
return status;
return ret;
} }
static ssize_t lan9252_write(struct file *file, const char *command_buff,
static ssize_t lan9252_write( size_t command_buff_size, loff_t *f_pos)
struct file *file, const char *command_buff,
size_t command_buff_size, loff_t *f_pos)
{ {
u8 *command; u8 *command;
int status=0; int ret = 0;
#ifdef DEBUG #ifdef DEBUG
int i; int i;
#endif #endif
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
LAN9252_LOCK; LAN9252_LOCK;
if (command_buff_size <= 0) { if (command_buff_size <= 0) {
dev_err(&lan9252_devices->dev, "command_buff_size(%d) <= 0 \n", dev_err(&lan9252->dev, "command_buff_size(%d) <= 0 \n",
command_buff_size); command_buff_size);
goto out; goto out;
} else { } else {
dev_dbg(&lan9252_devices->dev, "command_buff_size = %d\n", dev_dbg(&lan9252->dev, "command_buff_size = %d\n",
command_buff_size); command_buff_size);
} }
command = (u8 *)kmalloc((command_buff_size) * command = (u8 *)kmalloc((command_buff_size) * sizeof(u8),
sizeof(u8), GFP_KERNEL | GFP_DMA); GFP_KERNEL | GFP_DMA);
if (!command) { if (!command) {
dev_err(&lan9252_devices->dev, "write command buffer kmalloc" dev_err(&lan9252->dev, "write command kmalloc error\n");
" error\n"); ret = -ENOMEM;
status = -ENOMEM;
goto out; goto out;
} }
memset(command, 0, (command_buff_size) * sizeof(u8)); memset(command, 0, (command_buff_size) * sizeof(u8));
if (copy_from_user(command, command_buff, command_buff_size)) { if (copy_from_user(command, command_buff, command_buff_size)) {
dev_err(&lan9252_devices->dev, "%s() copy_from_user failed\n", dev_err(&lan9252->dev, "%s() copy_from_user failed\n",
__FUNCTION__); __FUNCTION__);
status = -EFAULT; ret = -EFAULT;
goto kfree_command; goto kfree_command;
} }
#ifdef DEBUG #ifdef DEBUG
for(i=0;i<command_buff_size;i++) for(i=0;i<command_buff_size;i++)
dev_dbg(&lan9252_devices->dev, "command[%d]=0x%x\n", i, dev_dbg(&lan9252->dev, "command[%d]=0x%x\n",i,command[i]);
command[i]);
#endif #endif
status = spi_write_then_read(lan9252_devices, command, ret = spi_write_then_read(lan9252, command,
command_buff_size, NULL, 0); command_buff_size, NULL, 0);
if (status < 0 ) { if (ret < 0) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read " dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
"failed status=%d\n", __FUNCTION__, status); "ret=%d\n", __FUNCTION__, ret);
goto kfree_command; goto kfree_command;
} }
@ -284,29 +254,30 @@ kfree_command:
out: out:
LAN9252_UNLOCK; LAN9252_UNLOCK;
return status;
return ret;
} }
static long lan9252_ioctl(struct file *file, unsigned int cmd, static long lan9252_ioctl(struct file *file, unsigned int cmd,
unsigned long argument) unsigned long argument)
{ {
int status; int ret;
LAN9252_LOCK; LAN9252_LOCK;
switch (cmd) {
case TEST:
status=lan9252_test();
break;
default: switch (cmd) {
status=0; case TEST:
break; ret = lan9252_test();
} break;
LAN9252_UNLOCK; default:
ret = 0;
break;
}
return status; LAN9252_UNLOCK;
return ret;
} }
@ -317,13 +288,11 @@ static const struct spi_device_id lan9252_id_table[] = {
MODULE_DEVICE_TABLE(spi, lan9252_id_table); MODULE_DEVICE_TABLE(spi, lan9252_id_table);
static const struct file_operations lan9252_fops = { static const struct file_operations lan9252_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = lan9252_open, .llseek = lan9252_llseek,
.release = lan9252_release, .write = lan9252_write,
.llseek = lan9252_llseek, .read = lan9252_read,
.write = lan9252_write, .unlocked_ioctl = lan9252_ioctl,
.read = lan9252_read,
.unlocked_ioctl = lan9252_ioctl,
}; };
static struct spi_driver lan9252_ethercat_driver = { static struct spi_driver lan9252_ethercat_driver = {
@ -335,80 +304,47 @@ static struct spi_driver lan9252_ethercat_driver = {
.remove = lan9252_ethercat_remove, .remove = lan9252_ethercat_remove,
}; };
struct miscdevice lan9252_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &lan9252_fops,
};
static int lan9252_ethercat_probe(struct spi_device *spi) static int lan9252_ethercat_probe(struct spi_device *spi)
{ {
int status; int ret;
dev_dbg(&spi->dev, "%s() called\n", __FUNCTION__);
mutex_init(&lock); mutex_init(&lock);
lan9252_devices = spi; lan9252 = spi;
if(lan9252_test()) if(lan9252_test())
dev_warn(&lan9252_devices->dev, "lan9252 not connected\n"); dev_warn(&spi->dev, "lan9252 not connected\n");
if (register_chrdev(LAN9252_MAJOR, ret = misc_register(&lan9252_miscdev);
lan9252_ethercat_driver.driver.name, &lan9252_fops)) { if (ret)
dev_err(&lan9252_devices->dev, "unable to get major %d for " goto misc_register_fail;
, LAN9252_MAJOR);
status = -ENODEV;
goto register_chrdev_fail;
}
lan9252_class = class_create(THIS_MODULE, dev_info(&spi->dev, "Probed\n");
lan9252_ethercat_driver.driver.name);
if (IS_ERR(lan9252_class)) {
status = PTR_ERR(lan9252_class);
goto class_create_fail;
}
id = MKDEV(LAN9252_MAJOR, 0);
dev = device_create(lan9252_class, NULL, id, NULL,
lan9252_ethercat_driver.driver.name);
if (IS_ERR(dev)) {
status = PTR_ERR(dev);
dev_err(dev, "device_create error %d\n", status);
goto device_create_fail;
}
dev_dbg(&lan9252_devices->dev, "spi->max_speed_hz=%d"
" spi->bits_per_word=%d spi->mode=%d\n", spi->max_speed_hz,
spi->bits_per_word, spi->mode);
dev_dbg(&lan9252_devices->dev, "spi->chip_select=%d spi->cs_gpio=%d\n",
spi->chip_select, spi->cs_gpio);
dev_info(&lan9252_devices->dev, "Probed\n");
return 0; return 0;
device_create_fail: misc_register_fail:
class_destroy(lan9252_class); dev_err(&spi->dev, "Probed failed : %d\n", ret);
class_create_fail: return ret;
unregister_chrdev(LAN9252_MAJOR,
lan9252_ethercat_driver.driver.name);
register_chrdev_fail:
dev_err(&lan9252_devices->dev, "Probed failed : %d\n", status);
return status;
} }
static int lan9252_ethercat_remove(struct spi_device *spi) static int lan9252_ethercat_remove(struct spi_device *spi)
{ {
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__); misc_deregister(&lan9252_miscdev);
device_destroy(lan9252_class, id); dev_info(&spi->dev, "Removed\n");
class_destroy(lan9252_class);
unregister_chrdev(LAN9252_MAJOR,
lan9252_ethercat_driver.driver.name);
dev_info(&lan9252_devices->dev, "Removed\n");
return 0; return 0;
} }
module_spi_driver(lan9252_ethercat_driver); module_spi_driver(lan9252_ethercat_driver);
MODULE_AUTHOR("tykwon@m2i.co.kr"); MODULE_AUTHOR("tykwon@m2i.co.kr");
MODULE_DESCRIPTION("Microchip LAN9252 Ethercat Driver"); MODULE_DESCRIPTION("Microchip LAN9252 Ethercat Driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL");

View File

@ -6,8 +6,8 @@ Required properties:
- reg: SPI chip select. - reg: SPI chip select.
Example: Example:
ethercat: lan9252@1 { ethercat: lan9252@1 {
compatible = "lan9252"; compatible = "lan9252";
spi-max-frequency = <20000000>; spi-max-frequency = <20000000>;
reg = <1>; reg = <1>;
}; };