赞
踩
应用端读写
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <error.h>
- #include <stdint.h>
- #include <sys/ioctl.h>
- #define SET_ADDR_CMD _IOW('S', 0x01, int)
- #define SET_REGNUM_CMD _IOW('S', 0x02, uint32_t)
-
- int main(int argc, char **argv)
- {
- int fd = open("/dev/switch-dev", O_RDWR);
- if (fd < 0)
- {
- perror("Failed to open device");
- return -1;
- }
-
- // 设置addr和regnum
- int ret = ioctl(fd, SET_ADDR_CMD, 0x04);
- ioctl(fd, SET_REGNUM_CMD, 0x01);
- printf("ret: %d\n", ret);
- // 读取上面设置addr和regnum下寄存器的值
- int val;
- ret = read(fd, &val, sizeof(val));
- printf("val: 0x%x, ret: %d\n", val, ret);
-
- val = 0x12;
- write(fd, &val, sizeof(val));
-
- close(fd);
-
- return 0;
- }

- #include <linux/module.h>
- #include <linux/platform_device.h>
- #include <linux/fs.h>
- #include <linux/cdev.h>
- #include <linux/device.h>
- #include <linux/mdio.h>
- #include <linux/of.h>
- #include <linux/of_mdio.h>
-
- #define DRIVER_NAME "rtl8306"
- #define DEVICE_NAME "switch-dev"
- #define NUM_MINORS 1
-
- #define MAGIC_DATA 'S'
- #define SET_ADDR_CMD _IOW(MAGIC_DATA, 0x01, int)
- #define SET_REGNUM_CMD _IOW(MAGIC_DATA, 0x02, u32)
-
- struct rtl8306_switch_phy_data {
- int addr;
- u32 regnum;
- u16 val;
- };
-
- struct rtl8306_switch_data {
- struct cdev cdev;
- struct device *device;
- struct mii_bus *bus;
- struct rtl8306_switch_phy_data phy;
- };
-
- static struct class *rtl8306_switch_class;
- static dev_t rtl8306_switch_dev_number;
- static struct rtl8306_switch_data rtl8306_switch;
-
- static int rtl8306_switch_open(struct inode *inode, struct file *filp)
- {
- struct rtl8306_switch_data *data;
-
- data = container_of(inode->i_cdev, struct rtl8306_switch_data, cdev);
- filp->private_data = data;
-
- return 0;
- }
-
- static ssize_t rtl8306_switch_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
- {
- struct rtl8306_switch_data *data = filp->private_data;
- struct mii_bus *bus = data->bus;
- struct rtl8306_switch_phy_data *phy = &data->phy;
- u16 val;
-
- // printk("+++ func: %s, line: %d +++, phy->addr: 0x%x, phy->regnum: 0x%x\n", __func__, __LINE__, phy->addr, phy->regnum);
-
- val = mdiobus_read(bus, phy->addr, phy->regnum);
- if (val < 0)
- return val;
-
- if (copy_to_user(buf, &val, sizeof(val)))
- return -EFAULT;
-
- return sizeof(val);
- }
-
- static ssize_t rtl8306_switch_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
- {
- struct rtl8306_switch_data *data = filp->private_data;
- struct mii_bus *bus = data->bus;
- struct rtl8306_switch_phy_data *phy = &data->phy;
- u16 val;
-
- if (copy_from_user(&val, buf, sizeof(val)))
- return -EFAULT;
-
- // printk("+++ func: %s, line: %d +++, val: 0x%x\n", __func__, __LINE__, val);
-
- return mdiobus_write(bus, phy->addr, phy->regnum, val);
- }
-
- static long rtl8306_switch_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- {
- struct rtl8306_switch_data *data = filp->private_data;
- struct rtl8306_switch_phy_data *phy = &data->phy;
-
- switch (cmd) {
- case SET_ADDR_CMD:
- phy->addr = arg;
- // printk("+++ func: %s, line: %d +++, phy->addr: 0x%x\n", __func__,__LINE__, phy->addr);
- break;
- case SET_REGNUM_CMD:
- phy->regnum = arg;
- // printk("+++ func: %s, line: %d +++, phy->regnum: 0x%x\n", __func__, __LINE__, phy->regnum);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
- }
- static struct file_operations rtl8306_switch_fops = {
- .owner = THIS_MODULE,
- .open = rtl8306_switch_open,
- .read = rtl8306_switch_read,
- .write = rtl8306_switch_write,
- .unlocked_ioctl = rtl8306_switch_ioctl,
- };
-
- static int rtl8306_switch_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- struct device_node *mdio_np;
- int ret;
-
- // printk("+++ func: %s, line: %d +++\n", __func__, __LINE__);
- mdio_np = of_parse_phandle(dev->of_node, "mdio-bus", 0);
- if (!mdio_np) {
- dev_err(dev, "Failed to get MDIO bus node\n");
- return -ENODEV;
- }
- rtl8306_switch.bus = of_mdio_find_bus(mdio_np);
- of_node_put(mdio_np);
- if (!rtl8306_switch.bus) {
- dev_err(dev, "Failed to find MDIO bus\n");
- return -ENODEV;
- }
- // Initialize character device
- cdev_init(&rtl8306_switch.cdev, &rtl8306_switch_fops);
- rtl8306_switch.cdev.owner = THIS_MODULE;
-
- // Allocate device numbers
- ret = alloc_chrdev_region(&rtl8306_switch_dev_number, 0, NUM_MINORS, DRIVER_NAME);
- if (ret < 0) {
- dev_err(dev, "Failed to allocate device numbers\n");
- return ret;
- }
-
- // Create device class
- rtl8306_switch.device = device_create(rtl8306_switch_class, dev, rtl8306_switch_dev_number, NULL, DEVICE_NAME);
- if (IS_ERR(rtl8306_switch.device)) {
- class_destroy(rtl8306_switch_class);
- unregister_chrdev_region(rtl8306_switch_dev_number, NUM_MINORS);
- dev_err(dev, "Failed to create device\n");
- return PTR_ERR(rtl8306_switch.device);
- }
-
- // Add character device to the system
- ret = cdev_add(&rtl8306_switch.cdev, rtl8306_switch_dev_number, NUM_MINORS);
- if (ret < 0) {
- device_destroy(rtl8306_switch_class, rtl8306_switch_dev_number);
- class_destroy(rtl8306_switch_class);
- unregister_chrdev_region(rtl8306_switch_dev_number, NUM_MINORS);
- dev_err(dev, "Failed to add character device\n");
- return ret;
- }
-
- dev_info(dev, "My Switch driver initialized\n");
-
- return 0;
- }
-
- static int rtl8306_switch_remove(struct platform_device *pdev)
- {
- cdev_del(&rtl8306_switch.cdev);
- device_destroy(rtl8306_switch_class, rtl8306_switch_dev_number);
- class_destroy(rtl8306_switch_class);
- unregister_chrdev_region(rtl8306_switch_dev_number, NUM_MINORS);
- dev_info(&pdev->dev, "My Switch driver removed\n");
-
- return 0;
- }
-
- static const struct of_device_id rtl8306_switch_of_match[] = {
- { .compatible = DRIVER_NAME, },
- { },
- };
- MODULE_DEVICE_TABLE(of, rtl8306_switch_of_match);
-
- static struct platform_driver rtl8306_switch_driver = {
- .probe = rtl8306_switch_probe,
- .remove = rtl8306_switch_remove,
- .driver = {
- .name = DRIVER_NAME,
- .of_match_table = rtl8306_switch_of_match,
- },
- };
- module_platform_driver(rtl8306_switch_driver);
-
- MODULE_AUTHOR("linshuoquan@126.com");
- MODULE_DESCRIPTION("RTL8306 Switch driver");
- MODULE_LICENSE("GPL");
-
-
-
-
-

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。