测试平台imx6q linux5.4.215

华为电信高清IPTV遥控器

使用其它遥控器可以更改key_table和user_id

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <linux/jiffies.h>
#include <asm/irq.h>#define DEVICE_DEBUG
//undefine DEVICE_DEBUGstruct key_table_t{unsigned char key_val;unsigned char key_code;unsigned char key_name[20];
};struct key_table_t key_table[]={{0xF2,   KEY_POWER,          "POWER"           },  //1{0xDC,   KEY_SLEEP,          "SLEEP"           },{0xF3,    KEY_LEFTMETA,       "TV+"            },{0xF4,    KEY_RIGHTMETA,      "TV-"         },{0xF1,    KEY_MEDIA,          "TV/IPTV"     },{0x98,    KEY_SOUND,          "VOL CANCEL"  },  //6{0x9C,   KEY_MUTE,           "MUTE"            },{0x8D,    KEY_SETUP,          "SETUP"           },{0xD6,    KEY_ROTATE_DISPLAY, "ROTATE_DISPLAY"},{0x91,  KEY_CHAT,           "LOOK BACK"       },{0xCD,    KEY_LINEFEED,       "LIVE"            },  //11{0x83,  KEY_PLAYCD,         "Request Play"    },{0xC3,    KEY_HELP,           "INFO/HELP"       },{0x88,    KEY_HOME,           "DESKTOP"     },{0x82,    KEY_MENU,           "MENU"            },{0xCA,    KEY_UP,             "UP"          },  //16        {0xD2,  KEY_DOWN,           "DOWN"            },{0x99,    KEY_LEFT,           "LEFT"            },{0xC1,    KEY_RIGHT,          "RIGHT"           },{0xCE,    KEY_ENTER,          "ENTER"           },{0x80,    KEY_VOLUMEUP,       "VOLUME+"        },  //21{0x81,  KEY_VOLUMEDOWN,     "VOLUME-"     },{0xDD,    KEY_PAGEUP,         "PAGE UP"     },{0x8C,    KEY_PAGEDOWN,       "PAGE DOWN"       },{0x85,    KEY_LEFTSHIFT,      "CHANEL+"        },{0x86,    KEY_RIGHTSHIFT,     "CHANEL-"     },  //26{0x92,  KEY_1,              "Num:1"           },{0x93,    KEY_2,              "Num:2"           },{0xCC,    KEY_3,              "Num:3"           },{0x8E,    KEY_4,              "Num:4"           },{0x8F,    KEY_5,              "Num:5"           },  //31{0xC8,  KEY_6,              "Num:6"           },{0x8A,    KEY_7,              "Num:7"           },{0x8B,    KEY_8,              "Num:8"           },{0xC4,    KEY_9,              "Num:9"           },{0x87,    KEY_0,              "Num:0"           },  //36{0xDA,  KEY_SEARCH,         "*"               },{0xD0,    KEY_INSERT,         "#"               },{0x95,    KEY_PLAYPAUSE,      "PLAY/PAUSE"  },{0xC5,    KEY_BACK,           "BACK"            },
};
#define KEY_NUM sizeof(key_table)/sizeof(key_table[0])struct ir_key_info_t{unsigned char user_id;unsigned int key_num;struct key_table_t *key_data;
};static struct ir_key_info_t ir_remote_keycode ={.user_id = 0xB2,.key_num = KEY_NUM,.key_data = key_table,
};struct remote_ctrl{struct input_dev *input;struct gpio_keys_button *button;unsigned int keycode[KEY_NUM];spinlock_t lock;struct work_struct work;
};
// IR timing
/*   │                 │     │                      │     │             │*   │   9ms   │ 4.5ms │     │560us│     1690us     │     │ 560us│ 560us│*   │<-----1350us---->│     │<-------2250us------->│     │<--1120us--->│*¯¯¯│_________│¯¯¯¯¯¯¯│_..._│_____│¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯│_..._│______│¯¯¯¯¯¯│__...*   │-----------------│-----│----------------------│     │-------------│----*   │---IR start up---│     │       Logic:1        │     │   Logic:0   │*/static int __inline ir_bus_startup_timing(int pin){int i;i = 0;while(1){if( 0 == ( (gpio_get_value(pin)) & 1 ) ){udelay(900);if( i>9 )return -1;i++;} //wait bus release;elsebreak;}i = 0;while(1){//0 1 2 3 4if( 1 == ( (gpio_get_value(pin)) & 1 ) ){udelay(900);if(i>4)      //5*900us + (program run time) > 4.5msreturn -1;    //ir repect statusi++;}elsebreak;         //ir nomoal status}return 0;
}static u32 __inline__ ir_bus_read_byte(struct remote_ctrl *hs0038)
{int j;//struct gpio_keys_button *button = hs0038->button;int ir_pin = hs0038->button->gpio;u32 tmp=0;for(j=1;j<=8;j++){      //每个字节8个bit的判断while( ((gpio_get_value(ir_pin)) & 1 ) ==0 );       //等待上升沿udelay(900);if(((gpio_get_value(ir_pin)) & 1) ==1 ){udelay(900);tmp=tmp|0x80;if(j<8) tmp=tmp>>1;}elseif(j<8)tmp=tmp>>1;//如果是"0",则向右移一位,自动补"0"}return tmp;
}
static unsigned int get_key_table_id(unsigned int kv)
{int id;for(id=0; id<KEY_NUM; id++){if(kv == key_table[id].key_val){if(KEY_NUM >= id)return  id;}}return 0xFFFF;
}static int hs0038_read_data(struct remote_ctrl *hs0038)
{//struct gpio_keys_button *button;int ir_pin;u8 user_id,n_user_id = 0;u8 k_val,nk_val = 0;int id=0;ir_pin = hs0038->button->gpio;gpio_direction_input(ir_pin);if( 0 != ir_bus_startup_timing(ir_pin)){printk("unknow ir startup timing.\n");return -1;}user_id  =  ir_bus_read_byte(hs0038); //user id low byten_user_id= (ir_bus_read_byte(hs0038));   //user id high bytek_val    =  ir_bus_read_byte(hs0038);   //user id low bytenk_val   = (ir_bus_read_byte(hs0038));   //user id high byteif( k_val&nk_val || user_id&n_user_id){//dev_info(hs0038->input->dev, "ir dat check sum error.\n");printk("data error or repect operater.\n");}else{
#ifdef DEVICE_DEBUGprintk("hs0038 read-> [user id]:0x%2X, [~user id]:0x%2X, [kv]:0x%2X, [~kv]0x%2X.\n",user_id, n_user_id,k_val, nk_val);
#endif}id = get_key_table_id(k_val);switch (user_id){case 0xB2:input_report_key(hs0038->input,key_table[id].key_code, 1);   //report pressinput_report_key(hs0038->input,key_table[id].key_code, 0); //report releaseinput_sync(hs0038->input);
#ifdef DEVICE_DEBUGprintk("val=0x%2X, code=0x%2X, remote name:%s.\n",key_table[id].key_val,key_table[id].key_code,key_table[id].key_name);
#endifbreak;default ://dev_info(hs0038->input->dev, "Unkonw ir remote button.\n");return -1;break;}return 0;
}void hs0038_do_work(struct work_struct *wk)
{
#if 0struct remote_ctrl *hs0038;hs0038 = container_of(wk, struct remote_ctrl, work);hs0038->button->irq = gpio_to_irq(hs0038->button->gpio);printk("do work\n");//hs0038_read(hs0038);irq_set_irq_type(hs0038->button->irq, IRQF_TRIGGER_FALLING);enable_irq(hs0038->button->irq);
#endifstruct remote_ctrl *hs0038;//struct gpio_keys_button *button;     //int irq;hs0038 = container_of(wk, struct remote_ctrl, work);//button = hs0038->button;       //irq = gpio_to_irq(button->gpio);hs0038_read_data(hs0038);//irq_set_irq_type(irq,  IRQF_TRIGGER_FALLING);enable_irq(hs0038->button->irq);}static irqreturn_t hs0038_irq_handler(int irq, void *dev_id)
{struct remote_ctrl *hs0038 = dev_id;disable_irq_nosync(irq);schedule_work(&hs0038->work);  //irq request function schedule, as follow INIT_WORKreturn IRQ_HANDLED;
}static int hs0038_gpio_init(struct platform_device *pdev)
{struct remote_ctrl *hs0038;struct gpio_keys_button *button;const char *desc;                   //description infoint ret;hs0038 = platform_get_drvdata(pdev);button = hs0038->button;desc   = button->desc ? button->desc : "HS0038 IR Remote";  //if unset decription inforet = gpio_request_one(button->gpio, GPIOF_IN, desc);if (ret < 0) {dev_err(&pdev->dev, "Failed to request GPIO %d, error %d\n",button->gpio, ret);return ret;}ret = gpio_to_irq( button->gpio );   //gpio pin config as irq inputif (ret < 0){dev_err(&pdev->dev, "Unable to get irq id for GPIO %d,error %d\n",button->gpio, ret);goto fail;}else{hs0038->button->irq = ret;dev_info(&pdev->dev, "irq:%d.\n", hs0038->button->irq);}ret = request_irq(  hs0038->button->irq,  //irq idhs0038_irq_handler,     //irq handler functionIRQF_TRIGGER_FALLING, //irq modehs0038->input->name,    //device namehs0038 );              //dev id/priv dataif (ret){dev_err(&pdev->dev, "Unable to claim irq %d; error %d\n", hs0038->button->irq, ret);goto fail;}ret = gpio_direction_input(button->gpio);if (ret < 0){dev_err(&pdev->dev, "Failed to configure direction for GPIO %d , error %d\n",button->gpio, ret);goto fail;}return 0;fail:gpio_free(button->gpio);return ret;
}
#define IMX_GPIO_NR(bank, nr)   (((bank) - 1) * 32 + (nr))
static int hs0038_probe(struct platform_device *pdev)
{int ret=0, i=0;struct device *dev = &pdev->dev;struct remote_ctrl *hs0038=NULL;dev_info(dev, "Remote cotrol probe.\n");hs0038 = kzalloc(sizeof(struct remote_ctrl),GFP_KERNEL);hs0038 ->button = kzalloc(sizeof(struct gpio_keys_button),GFP_KERNEL);platform_set_drvdata(pdev, hs0038);hs0038->input = input_allocate_device();if (!hs0038->input || !hs0038){dev_err(dev, "Failed to allocate state\n");ret= -ENOMEM;goto err_free_mem;}hs0038->input->name        = "HS0038 IR Remote control";hs0038->input->phys       = "hs0038/input1";hs0038->input->id.bustype    = BUS_HOST;hs0038->input->id.vendor  = 0xabce;hs0038->input->id.product   = 0xecba;hs0038->input->id.version   = 0x0100;hs0038->input->evbit[0]     = BIT(EV_KEY);hs0038->input->keycode     = hs0038->keycode;hs0038->input->keycodesize  = sizeof(unsigned int);hs0038->input->keycodemax     = KEY_NUM;set_bit(EV_KEY, hs0038->input->evbit);for (i = 0; i < KEY_NUM; i++){hs0038->keycode[i]= ir_remote_keycode.key_data[i].key_code;set_bit(hs0038->keycode[i], hs0038->input->keybit);}INIT_WORK(&hs0038->work, hs0038_do_work);   //dcspin_lock_init(&hs0038->lock);hs0038->button->gpio = IMX_GPIO_NR(1, 6);hs0038->button->desc = "HS0038 IR Remote";ret=hs0038_gpio_init(pdev);if(ret)goto err_gpio_free;ret = input_register_device(hs0038->input);if (ret < 0){dev_err(dev,"probe input device register failed.\n");goto  err_input_free;}return 0;err_input_free:input_free_device(hs0038->input);err_gpio_free:gpio_free(hs0038->button->gpio);err_free_mem:kfree(hs0038->input);kfree(hs0038->button);kfree(hs0038);return ret;
}
static int hs0038_remove(struct platform_device *pdev)
{struct device *dev = &pdev->dev;struct remote_ctrl *hs0038;hs0038 = platform_get_drvdata(pdev);dev_info(dev, "Remote cotrol remove.\n");input_unregister_device(hs0038->input);//input_free_device(hs0038->input);free_irq(hs0038->button->irq, hs0038);gpio_free(hs0038->button->gpio);kfree(hs0038->input);kfree(hs0038->button);kfree(hs0038);return 0;
}static const struct of_device_id  hs0038_of_match[] = {{ .compatible = "hs0038", },{ },
};static struct platform_driver hs0038_driver = {.probe        = hs0038_probe,.remove     = hs0038_remove,.driver        = {.name   = "IR Remote",.owner = THIS_MODULE,.of_match_table = of_match_ptr(hs0038_of_match),},
};
static int __init hs0038_init(void)
{return platform_driver_register(&hs0038_driver);
}static void __exit hs0038_exit(void)
{platform_driver_unregister(&hs0038_driver);
}module_init(hs0038_init);
module_exit(hs0038_exit);MODULE_AUTHOR("YuanBin");
MODULE_DESCRIPTION("GPIO IR Remote Driver");
MODULE_LICENSE("GPL");

Linux红外遥控驱动HS0038相关推荐

  1. 移动咪咕盒子红外遥控驱动

    最近入手了一块显示屏,又惊喜的发现移动咪咕盒子一直落灰,(反正盒子没破解也不能看电视),那给我的讯为4412开发板刷个安卓系统,写个红外遥控驱动烧进去,这样就能用咪咕盒子的遥控器看电视了.说干就干,开 ...

  2. android红外遥控驱动

    在 Linux 内核中,IR 驱动仅支持 NEC 编码格式. 设备树文件 pwm0: pwm@ff680000 {compatible = "rockchip,rk-pwm";re ...

  3. 嵌入式Linux红外遥控,树莓派红外遥控 (lirc、gpio-ir)—— 一篇就够了!

    超简单!树莓派红外遥控配置 前言 第一步:驱动配置(/boot/config.txt) 第二步:安装lirc,并配置 第三步:测试 第四步:按键配置(/etc/lirc/lircd.conf) 第五步 ...

  4. 嵌入式Linux红外遥控,一个简单的IAL分析(红外遥控)(转)

    简单的IAL分析 一.程序说明 1.下面程序是基于一个红外的设备文件,从该设备中能接收到红外遥控的硬件编码. 2.两个文件需要覆盖掉libmingiui*/src/ial/中的两个文件编译时加上 -- ...

  5. linux红外遥控进程,46.Linux-分析rc红外遥控平台驱动框架,修改内核的NEC解码函数BUG(1)...

    内核版本         :  Linux 3.10.14 rc红外接收类型:  GPIO 类型的NEC红外编码 本章内容 1)rc体系结构分析 2) 分析红外platform_driver平台驱动框 ...

  6. linux 怎么往内核加驱动,向Linux内核添加驱动

    Linux内核中提供了很多设备的驱动代码,但每个项目中总会需要添加我们自己的驱动,比如我们需要添加红外遥控驱动.我们可以先独立去编写和调试这个驱动,等成熟后应该放到内核目录树中,使用make modu ...

  7. linux树莓派网易云音乐,基于树莓派的红外遥控版网易云音乐播放器

    基于树莓派的红外遥控版网易云音乐播放器.下面是遥控键盘示意图: CH- CH CH+ << >> || - + EQ 0 100+ 200+ 1 2 3 4 5 6 7 8 9 ...

  8. 搭建红外遥控arm-hadoop集群过程

    很多人玩开发板用树莓派,树莓派的确很好,但是对于hadoop来说,内存有点小,只有512MB.所以我找了一圈,最后用的是国内一个开源硬件团队的产品叫CubieTruck.内存有2G,板载存储有8G,千 ...

  9. 遥控窗帘c语言程序,使用AT89C2051的红外遥控窗帘

    本文介绍一款使用微电脑管理的.红外遥控器控制的多功能窗帘控制器.该窗帘控制器采用89C2051单片机的最小系统设计,控制一个220V的可逆.变速电动机控制窗帘的拉开和关闭.窗帘控制器可以使用红外遥控器 ...

最新文章

  1. centos ezhttp mysql_CentOS安装mysq
  2. AlphaCode惊世登场!编程版“阿法狗”悄悄参赛,击败一半程序员
  3. Nginx配置与使用
  4. MySQL AS:设置别名
  5. LVS NAT/DR
  6. 前端学习(2761):uni-app样式的学习
  7. rman 备份后恢复整个数据库文件的操作
  8. java获取当前时间星期几_java怎么获取当前日期是星期几
  9. linux网络命令详解
  10. Python字符串index()方法应用案例一则
  11. #动态规划 LeetCode 120 三角形最小路径和
  12. 从架构设计到系统实施-基于.NET 3.0的全新企业应用之基于WCF的系统服务
  13. matlab自动交易系统 浏览
  14. 修改tomcat版本号解决eclipse中tomcat版本不对应
  15. html文件转为其他格式文件格式,HTML文件转Word文件格式
  16. 工程制图与计算机绘图试卷A,工程制图与计算机绘图第4章
  17. C语言-打印菱形三角形等图形
  18. Python基础知识-pycharm版 第3节
  19. python 桑基图_3行代码基于python的matplotlib绘制桑基图
  20. Linux的时间和时区设置

热门文章

  1. 微信如何备份全部的聊天记录到电脑
  2. WSF操作系统抽象层学习笔记 (一) ---简介和内存管理
  3. 硬件工程师c语言编程,硬件工程师:单片机编程,我用C语言
  4. #if defined()的用法
  5. 1.23CSS3部分基本样式(1)
  6. Torque中文版(车况监控)
  7. matlab lzc,人脸分割 matlab程序
  8. JS高级+ES678
  9. 全球及中国坐式充气皮划艇行业产能产量需求及发展前景调研报告2022-2027年
  10. gdpr数据处理_关于GDPR下数据同意的知识