分享

platform设备led(ok6410)

 champion_xu 2012-06-10
这里记录了platform总线设备的文件编写。
device部分:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>

static struct resource led_resource[] = {
    [0] = {
        .start = 0x7F008820,
        .end   = 0x7F008820 + 8 -1,
        .flags = IORESOURCE_MEM,
    },
};

static void led_release(struct device * dev)
{
    printk("remove device\n");
}

static struct platform_device led_dev = {
    .name = "s3c6410leds",
    .id   = -1,
    .num_resources = ARRAY_SIZE(led_resource),
    .resource = led_resource,
    .dev = {
        .release = led_release,
    },
};

static int leddev_init(void)
{
    platform_device_register(&led_dev);
    return 0;
}

static void leddev_exit(void)
{
    platform_device_unregister(&led_dev);
}

module_init(leddev_init);
module_exit(leddev_exit);

MODULE_LICENSE("GPL");

driver部分:
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/ioctl.h>
#include<linux/types.h>
#include<linux/cdev.h>
#include<linux/device.h>
#include<linux/fs.h>
#include <mach/map.h>
#include <asm/io.h>  //包含了IO内存的相关操作
#include <linux/platform_device.h>

#define DEVICE_NAME "s3c6410leds"
#define LED_ON 1
#define LED_OFF 0
dev_t devid;

volatile unsigned long *gpmcon;
volatile unsigned long *gpmdat;
volatile unsigned long *gpmup;

static int leds_open(struct inode *inode , struct file *file)
{
  unsigned tmp;

  tmp=ioread32(gpmcon);
  mb();
  tmp |= 0x1111;  //设置为输出
  iowrite32(tmp,gpmcon);

  mb();   //设置读写操作屏障,保证读写按照当前所写的顺序进行

  tmp=ioread32(gpmup);

  mb();  //设置读写操作屏障,保证读写按照当前所写的顺序进行

  tmp |= 0xaa; //设置上拉电阻开启
  iowrite32(tmp,gpmup);
 

  return 0;
}


static long leds_ioctl( struct file *filp,unsigned int cmd,
                        unsigned long arg)
                     
{
  unsigned tmp;

  if(arg>4) return -EINVAL;
  tmp = ioread32(gpmdat);
  mb();

  switch(cmd)
  {
    case LED_ON:  tmp &= ~(1<<arg); iowrite32(tmp,gpmdat);
                  return 0;
    case LED_OFF: tmp |= 1<<arg; iowrite32(tmp,gpmdat);
                  return 0;
    default: return -EINVAL;
  }
}

static struct file_operations leds_ops = {
    .owner = THIS_MODULE,
    .open = leds_open,
    .unlocked_ioctl = leds_ioctl,
};

static struct cdev *cdev_led;
static struct class *led_class;
static struct resource *ret;

static int led_probe(struct platform_device *pdev)
{   
    int msize,val;
    ret = platform_get_resource(pdev,IORESOURCE_MEM, 0);
    msize = ret->end - ret->start + 1;
   
    if(!request_mem_region(ret->start,msize,DEVICE_NAME)) printk("request con error\n");
    else gpmcon=ioremap_nocache(ret->start,msize);

    gpmdat = gpmcon + 1;
    gpmup = gpmcon + 2;

    val = alloc_chrdev_region(&devid,0,1,DEVICE_NAME);
      if(val) return -1;

    cdev_led = cdev_alloc();
      cdev_init(cdev_led,&leds_ops);
      val = cdev_add(cdev_led,devid,1);
      if(val)
      {
            printk(KERN_INFO "Add device led error!\n");
            return -1;
      }
 
      led_class = class_create(THIS_MODULE,DEVICE_NAME);
      device_create(led_class,NULL,devid,NULL,"%s",DEVICE_NAME);

    printk(KERN_INFO "LED Initilized I'm in! ^_^ \n");
      return 0;
}

static int led_remove(struct platform_device *pdev)
{
    iounmap(gpmcon);
      release_mem_region(ret->start,(ret->end - ret->start + 1));
      cdev_del(cdev_led);
      device_destroy(led_class,devid);
      class_destroy(led_class); 
      unregister_chrdev_region(devid, 1);
    return 0;
}

struct platform_driver led_driver = {
    .probe = led_probe,
    .remove = led_remove,
    .driver = {
        .owner    = THIS_MODULE,
        .name = "s3c6410leds",
    },
};

static int __init leddrv_init(void)
{
    platform_driver_register(&led_driver);
    return 0;
}

static void __exit leddrv_exit(void)
{
    platform_driver_unregister(&led_driver);
}

module_init(leddrv_init);
module_exit(leddrv_exit);

MODULE_LICENSE("GPL");

makefile部分:
KDIR = /home/xu/Documents/linux-3.0.24
PWD  = $(shell pwd)

all:
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
    rm -rf *.o *~ *.mod.o *.mod.c

obj-m += led_dev.o
obj-m += led_drv.o

编译后会产生两个.ko文件,需要都加载上才能正常工作。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多