从rk3188下摘录出来的hym8563源码

/*drivers/rtc/rtc-HYM8563.h - driver for HYM8563** Copyright (C) 2010 ROCKCHIP, Inc.** This software is licensed under the terms of the GNU General Public* License version 2, as published by the Free Software Foundation, and* may be copied, distributed, and modified under those terms.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the* GNU General Public License for more details.*/#ifndef _DRIVERS_HYM8563_H
#define _DRIVERS_HYM8563_H#define   RTC_CTL1      0x00
#define   RTC_CTL2      0x01
#define   RTC_SEC       0x02
#define   RTC_MIN       0x03
#define   RTC_HOUR      0x04
#define   RTC_DAY       0x05
#define   RTC_WEEK      0x06
#define   RTC_MON       0x07
#define   RTC_YEAR      0x08
#define   RTC_A_MIN     0x09
#define   RTC_A_HOUR    0x0A
#define   RTC_A_DAY     0x0B
#define   RTC_A_WEEK    0x0C
#define   RTC_CLKOUT    0x0D
#define   RTC_T_CTL     0x0E
#define   RTC_T_COUNT   0x0F
#define   CENTURY   0x80
#define   TI        0x10
#define   AF        0x08
#define   TF        0x04
#define   AIE       0x02
#define   TIE       0x01
#define   FE        0x80
#define   TE        0x80
#define   FD1       0x02
#define   FD0       0x01
#define   TD1       0x02
#define   TD0       0x01
#define   VL        0x80#define HYM8563_REG_LEN     0x10
#define HYM8563_RTC_SECTION_LEN 0x07struct hym8563_platform_data {unsigned int speed;unsigned int mode;unsigned int reg_byte_cnt;
};#endif  /*_DRIVERS_HYM8563_H*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
#include <linux/delay.h>
#include <linux/wakelock.h>
#include <linux/slab.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#include "rtc-HYM8563.h"
#include <mach/board.h>#define RTC_SPEED   200 * 1000
#define pr_fmt(fmt) "rtc: %s: " fmt, __func__
struct hym8563 {int irq;struct i2c_client *client;struct work_struct work;struct mutex mutex;struct rtc_device *rtc;int exiting;struct rtc_wkalrm alarm;struct wake_lock wake_lock;
};
static struct i2c_client *gClient = NULL;static int hym8563_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
{int ret; ret = i2c_master_reg8_recv(client, reg, buf, len, RTC_SPEED);return ret;
}static int hym8563_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], __u16 len)
{int ret; ret = i2c_master_reg8_send(client, reg, buf, (int)len, RTC_SPEED);return ret;
}int hym8563_enable_count(struct i2c_client *client, int en)
{struct hym8563 *hym8563 = i2c_get_clientdata(client);   u8 regs[2];if (!hym8563)return -1;if (en) {hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);regs[0] |= TIE;hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);regs[0] = 0;regs[0] |= (TE | TD1);hym8563_i2c_set_regs(client, RTC_T_CTL, regs, 1);}else {hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);regs[0] &= ~TIE;hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);regs[0] = 0;regs[0] |= (TD0 | TD1);hym8563_i2c_set_regs(client, RTC_T_CTL, regs, 1);}return 0;
}//0 < sec <=255
int hym8563_set_count(struct i2c_client *client, int sec)
{   struct hym8563 *hym8563 = i2c_get_clientdata(client);u8 regs[2];if (!hym8563)return -1;      if (sec >= 255)regs[0] = 255;else if (sec <= 1)regs[0] = 1;elseregs[0] = sec;  hym8563_i2c_set_regs(client, RTC_T_COUNT, regs, 1); return 0;
}/*the init of the hym8563 at first time */
static int hym8563_init_device(struct i2c_client *client)
{struct hym8563 *hym8563 = i2c_get_clientdata(client);u8 regs[2];int sr;mutex_lock(&hym8563->mutex);regs[0]=0;sr = hym8563_i2c_set_regs(client, RTC_CTL1, regs, 1);       if (sr < 0)goto exit;  //enable clkoutregs[0] = 0x80;sr = hym8563_i2c_set_regs(client, RTC_CLKOUT, regs, 1);if (sr < 0)goto exit;/*enable alarm && count interrupt*/sr = hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);if (sr < 0)goto exit;regs[0] = 0x0;regs[0] |= (AIE | TIE);sr = hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);if (sr < 0)goto exit;sr = hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);if (sr < 0)goto exit;sr = hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);if (sr < 0) {pr_err("read CTL2 err\n");goto exit;}if(regs[0] & (AF|TF)){regs[0] &= ~(AF|TF);sr = hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);}exit:mutex_unlock(&hym8563->mutex);return sr;
}static int hym8563_read_datetime(struct i2c_client *client, struct rtc_time *tm)
{struct hym8563 *hym8563 = i2c_get_clientdata(client);u8 i,regs[HYM8563_RTC_SECTION_LEN] = { 0, };mutex_lock(&hym8563->mutex);
//  for (i = 0; i < HYM8563_RTC_SECTION_LEN; i++) {
//      hym8563_i2c_read_regs(client, RTC_SEC+i, &regs[i], 1);
//  }hym8563_i2c_read_regs(client, RTC_SEC, regs, HYM8563_RTC_SECTION_LEN);mutex_unlock(&hym8563->mutex);tm->tm_sec = bcd2bin(regs[0x00] & 0x7F);tm->tm_min = bcd2bin(regs[0x01] & 0x7F);tm->tm_hour = bcd2bin(regs[0x02] & 0x3F);tm->tm_mday = bcd2bin(regs[0x03] & 0x3F);tm->tm_wday = bcd2bin(regs[0x04] & 0x07);   tm->tm_mon = bcd2bin(regs[0x05] & 0x1F) ; tm->tm_mon -= 1;            //inorder to cooperate the systerm timetm->tm_year = bcd2bin(regs[0x06] & 0xFF);if(regs[5] & 0x80)tm->tm_year += 1900;elsetm->tm_year += 2000;tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);  tm->tm_year -= 1900;            //inorder to cooperate the systerm timeif(tm->tm_year < 0)tm->tm_year = 0;    tm->tm_isdst = 0;   pr_debug("%4d-%02d-%02d(%d) %02d:%02d:%02d\n",1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,tm->tm_hour, tm->tm_min, tm->tm_sec);return 0;
}static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{return hym8563_read_datetime(to_i2c_client(dev), tm);
}static int hym8563_set_time(struct i2c_client *client, struct rtc_time *tm)
{struct hym8563 *hym8563 = i2c_get_clientdata(client);u8 regs[HYM8563_RTC_SECTION_LEN] = { 0, };u8 mon_day,i;u8 ret = 0;pr_debug("%4d-%02d-%02d(%d) %02d:%02d:%02d\n",1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,tm->tm_hour, tm->tm_min, tm->tm_sec);mon_day = rtc_month_days((tm->tm_mon), tm->tm_year + 1900);if(tm->tm_sec >= 60 || tm->tm_sec < 0 )     //set  secregs[0x00] = bin2bcd(0x00);elseregs[0x00] = bin2bcd(tm->tm_sec);if(tm->tm_min >= 60 || tm->tm_min < 0 )     //set  minregs[0x01] = bin2bcd(0x00);elseregs[0x01] = bin2bcd(tm->tm_min);if(tm->tm_hour >= 24 || tm->tm_hour < 0 )       //set  hourregs[0x02] = bin2bcd(0x00);elseregs[0x02] = bin2bcd(tm->tm_hour);if((tm->tm_mday) > mon_day)             //if the input month day is bigger than the biggest day of this month, set the biggest dayregs[0x03] = bin2bcd(mon_day);else if((tm->tm_mday) > 0)regs[0x03] = bin2bcd(tm->tm_mday);else if((tm->tm_mday) <= 0)regs[0x03] = bin2bcd(0x01);if( tm->tm_year >= 200)     // year >= 2100regs[0x06] = bin2bcd(99);   //year = 2099else if(tm->tm_year >= 100)         // 2000 <= year < 2100regs[0x06] = bin2bcd(tm->tm_year - 100);else if(tm->tm_year >= 0){              // 1900 <= year < 2000regs[0x06] = bin2bcd(tm->tm_year);  regs[0x05] |= 0x80; }else{                                  // year < 1900regs[0x06] = bin2bcd(0);    //year = 1900regs[0x05] |= 0x80; }   regs[0x04] = bin2bcd(tm->tm_wday);      //set  the  weekdayregs[0x05] = (regs[0x05] & 0x80)| (bin2bcd(tm->tm_mon + 1) & 0x7F);     //set  the  monthmutex_lock(&hym8563->mutex);
//  for(i=0;i<HYM8563_RTC_SECTION_LEN;i++){
//      ret = hym8563_i2c_set_regs(client, RTC_SEC+i, &regs[i], 1);
//  }hym8563_i2c_set_regs(client, RTC_SEC, regs, HYM8563_RTC_SECTION_LEN);mutex_unlock(&hym8563->mutex);return 0;
}static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
{return hym8563_set_time(to_i2c_client(dev), tm);
}static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
{struct i2c_client *client = to_i2c_client(dev);struct hym8563 *hym8563 = i2c_get_clientdata(client);u8 regs[4] = { 0, };    pr_debug("enter\n");mutex_lock(&hym8563->mutex);hym8563_i2c_read_regs(client, RTC_A_MIN, regs, 4);regs[0] = 0x0;regs[0] |= TIE;hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);mutex_unlock(&hym8563->mutex);return 0;
}static int hym8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{   struct i2c_client *client = to_i2c_client(dev);struct hym8563 *hym8563 = i2c_get_clientdata(client);struct rtc_time now, *tm = &alarm->time;u8 regs[4] = { 0, };u8 mon_day; unsigned long   alarm_sec, now_sec;int diff_sec = 0;pr_debug("%4d-%02d-%02d(%d) %02d:%02d:%02d enabled %d\n",1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,tm->tm_hour, tm->tm_min, tm->tm_sec, alarm->enabled);       hym8563_read_datetime(client, &now);    mutex_lock(&hym8563->mutex);rtc_tm_to_time(tm, &alarm_sec);rtc_tm_to_time(&now, &now_sec); diff_sec = alarm_sec - now_sec; if((diff_sec > 0) && (diff_sec < 256)){   printk("%s:diff_sec= %ds , use time\n",__func__, diff_sec);hym8563_enable_count(client, 1);                hym8563_set_count(client, diff_sec);}else{               printk("%s:diff_sec= %ds , use alarm\n",__func__, diff_sec);hym8563_enable_count(client, 0);        if(tm->tm_sec > 0){rtc_tm_to_time(tm, &alarm_sec);rtc_time_to_tm(alarm_sec, tm);}hym8563->alarm = *alarm;regs[0] = 0x0;hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);mon_day = rtc_month_days(tm->tm_mon, tm->tm_year + 1900);hym8563_i2c_read_regs(client, RTC_A_MIN, regs, 4);if (tm->tm_min >= 60 || tm->tm_min < 0)     //set  minregs[0x00] = bin2bcd(0x00) & 0x7f;elseregs[0x00] = bin2bcd(tm->tm_min) & 0x7f;if (tm->tm_hour >= 24 || tm->tm_hour < 0)   //set  hourregs[0x01] = bin2bcd(0x00) & 0x7f;elseregs[0x01] = bin2bcd(tm->tm_hour) & 0x7f;regs[0x03] = bin2bcd (tm->tm_wday) & 0x7f;/* if the input month day is bigger than the biggest day of this month, set the biggest day */if (tm->tm_mday > mon_day)regs[0x02] = bin2bcd(mon_day) & 0x7f;else if (tm->tm_mday > 0)regs[0x02] = bin2bcd(tm->tm_mday) & 0x7f;else if (tm->tm_mday <= 0)regs[0x02] = bin2bcd(0x01) & 0x7f;hym8563_i2c_set_regs(client, RTC_A_MIN, regs, 4);   hym8563_i2c_read_regs(client, RTC_A_MIN, regs, 4);  hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);if (alarm->enabled == 1)regs[0] |= AIE;elseregs[0] &= 0x0;regs[0] |= TIE;hym8563_i2c_set_regs(client, RTC_CTL2, regs, 1);hym8563_i2c_read_regs(client, RTC_CTL2, regs, 1);if(diff_sec <= 0){       pr_info("alarm sec  <= now sec\n");}           }   mutex_unlock(&hym8563->mutex);return 0;
}#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
static int hym8563_i2c_open_alarm(struct i2c_client *client)
{u8 data;    hym8563_i2c_read_regs(client, RTC_CTL2, &data, 1);data |= AIE;hym8563_i2c_set_regs(client, RTC_CTL2, &data, 1);return 0;
}static int hym8563_i2c_close_alarm(struct i2c_client *client)
{u8 data;    hym8563_i2c_read_regs(client, RTC_CTL2, &data, 1);data &= ~AIE;hym8563_i2c_set_regs(client, RTC_CTL2, &data, 1);return 0;
}static int hym8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{struct i2c_client *client = to_i2c_client(dev);switch (cmd) {case RTC_AIE_OFF:if(hym8563_i2c_close_alarm(client) < 0)goto err;break;case RTC_AIE_ON:if(hym8563_i2c_open_alarm(client))goto err;break;default:return -ENOIOCTLCMD;}   return 0;
err:return -EIO;
}
#else
#define hym8563_rtc_ioctl NULL
#endif#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
static int hym8563_rtc_proc(struct device *dev, struct seq_file *seq)
{return 0;
}
#else
#define hym8563_rtc_proc NULL
#endifstatic irqreturn_t hym8563_wakeup_irq(int irq, void *data)
{struct hym8563 *hym8563 = data; struct i2c_client *client = hym8563->client;    u8 value;mutex_lock(&hym8563->mutex);hym8563_i2c_read_regs(client, RTC_CTL2, &value, 1);value &= ~(AF|TF);hym8563_i2c_set_regs(client, RTC_CTL2, &value, 1);  mutex_unlock(&hym8563->mutex);rtc_update_irq(hym8563->rtc, 1, RTC_IRQF | RTC_AF | RTC_UF);//printk("%s:irq=%d\n",__func__,irq);return IRQ_HANDLED;
}static const struct rtc_class_ops hym8563_rtc_ops = {.read_time  = hym8563_rtc_read_time,.set_time   = hym8563_rtc_set_time,.read_alarm = hym8563_rtc_read_alarm,.set_alarm  = hym8563_rtc_set_alarm,.ioctl      = hym8563_rtc_ioctl,.proc       = hym8563_rtc_proc
};static int __devinit hym8563_probe(struct i2c_client *client, const struct i2c_device_id *id)
{int rc = 0;u8 reg = 0;struct hym8563 *hym8563;struct rtc_device *rtc = NULL;struct rtc_time tm_read, tm = {.tm_wday = 6,.tm_year = 111,.tm_mon = 0,.tm_mday = 1,.tm_hour = 12,.tm_min = 0,.tm_sec = 0,};  if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))return -ENODEV;hym8563 = kzalloc(sizeof(struct hym8563), GFP_KERNEL);if (!hym8563) {return -ENOMEM;}gClient = client;   hym8563->client = client;hym8563->alarm.enabled = 0;mutex_init(&hym8563->mutex);wake_lock_init(&hym8563->wake_lock, WAKE_LOCK_SUSPEND, "rtc_hym8563");i2c_set_clientdata(client, hym8563);hym8563_init_device(client);    //时钟模块初始化hym8563_enable_count(client, 0);//关闭计时// check power downhym8563_i2c_read_regs(client,RTC_SEC,&reg,1);if (reg&0x80) {dev_info(&client->dev, "clock/calendar information is no longer guaranteed\n");hym8563_set_time(client, &tm);}hym8563_read_datetime(client, &tm_read);    //read time from hym8563if(((tm_read.tm_year < 70) | (tm_read.tm_year > 137 )) | (tm_read.tm_mon == -1) | (rtc_valid_tm(&tm_read) != 0)) //if the hym8563 haven't initialized{hym8563_set_time(client, &tm);  //initialize the hym8563}   if(gpio_request(client->irq, "rtc gpio")){dev_err(&client->dev, "gpio request fail\n");gpio_free(client->irq);goto exit;}hym8563->irq = gpio_to_irq(client->irq);gpio_pull_updown(client->irq,GPIOPullUp);if (request_threaded_irq(hym8563->irq, NULL, hym8563_wakeup_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->dev.driver->name, hym8563) < 0){printk("unable to request rtc irq\n");goto exit;}   enable_irq_wake(hym8563->irq);rtc = rtc_device_register(client->name, &client->dev,&hym8563_rtc_ops, THIS_MODULE);if (IS_ERR(rtc)) {rc = PTR_ERR(rtc);rtc = NULL;goto exit;}hym8563->rtc = rtc;return 0;exit:if (rtc)rtc_device_unregister(rtc);if (hym8563) {wake_lock_destroy(&hym8563->wake_lock);kfree(hym8563);}return rc;
}static int __devexit hym8563_remove(struct i2c_client *client)
{struct hym8563 *hym8563 = i2c_get_clientdata(client);if (hym8563->irq > 0) {mutex_lock(&hym8563->mutex);hym8563->exiting = 1;mutex_unlock(&hym8563->mutex);free_irq(hym8563->irq, hym8563);cancel_work_sync(&hym8563->work);}rtc_device_unregister(hym8563->rtc);wake_lock_destroy(&hym8563->wake_lock);kfree(hym8563);hym8563 = NULL;return 0;
}void hym8563_shutdown(struct i2c_client * client)
{   u8 regs[2]; int ret;    //disable clkoutregs[0] = 0x00; ret=hym8563_i2c_set_regs(client, RTC_CLKOUT, regs, 1);  if(ret<0)   printk("rtc shutdown is error\n");
}static const struct i2c_device_id hym8563_id[] = {{ "rtc_hym8563", 0 },{ }
};
MODULE_DEVICE_TABLE(i2c, hym8563_id);//构建i2c_driver
static struct i2c_driver hym8563_driver = {.driver     = {.name   = "rtc_hym8563",.owner  = THIS_MODULE,},.probe      = hym8563_probe,.remove     = __devexit_p(hym8563_remove),
#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188) || defined(CONFIG_ARCH_RKPX3)//.shutdown=hym8563_shutdown,
#else.shutdown=hym8563_shutdown,
#endif.id_table   = hym8563_id,
};//注册i2c_driver
static int __init hym8563_init(void)
{return i2c_add_driver(&hym8563_driver);
}static void __exit hym8563_exit(void)
{i2c_del_driver(&hym8563_driver);
}MODULE_AUTHOR("lhh lhh@rock-chips.com");
MODULE_DESCRIPTION("HYM8563 RTC driver");
MODULE_LICENSE("GPL");module_init(hym8563_init);
module_exit(hym8563_exit);

关于IIC驱动的介绍,可查阅
http://www.cnblogs.com/liugf05/archive/2012/12/05/2803795.html
http://www.cnblogs.com/simonshi/archive/2011/02/24/1963426.html

某些关键函数分析
注册平台驱动的函数为platform_driver_register()详见
http://blog.csdn.net/yili_xie/article/details/5193609
对应IIC设备,对应的注册IIC驱动的函数为i2c_add_driver();
http://blog.csdn.net/zclongembedded/article/details/8207722

i2c_check_functionality用来判定设配器的能力

wake_lock_init()用于初始化一个新锁,type参数指定了锁的类型,详看
http://blog.csdn.net/g_salamander/article/details/7978772
gpio_request(client->irq, “rtc gpio”)//申请该gpio,并设置名字为rtc gpio
hym8563->irq = gpio_to_irq(client->irq);//将申请到的io口设置中断功能
gpio_pull_updown(client->irq,GPIOPullUp);//上拉该gpio。
该gpio在板级文件kernel/arm/mach-rkpx3/board-rkpx3-sdk. c中定义。

static struct i2c_board_info __initdata i2c1_info[] = {
#if defined (CONFIG_RTC_HYM8563){.type           = "rtc_hym8563",.addr           = 0x51,.flags          = 0,.irq            = RK30_PIN0_PB5,},
#endif
}
i2c_register_board_info(1, i2c1_info, ARRAY_SIZE(i2c1_info));
}

request_threaded_irq申请线程中断,为什么不用request_irq,请查阅
http://www.cnblogs.com/leaven/archive/2010/09/09/1822018.html

request_threaded_irq(hym8563->irq, NULL, hym8563_wakeup_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->dev.driver->name, hym8563)
RQF_TRIGGER_LOW电平触发,IRQF_ONESHOT代表只触发一次,详细介绍见
http://www.wowotech.net/linux_kenrel/request_threaded_irq.html

static irqreturn_t hym8563_wakeup_irq(int irq, void *data)
{struct hym8563 *hym8563 = data; struct i2c_client *client = hym8563->client;    u8 value;mutex_lock(&hym8563->mutex);hym8563_i2c_read_regs(client, RTC_CTL2, &value, 1);value &= ~(AF|TF);hym8563_i2c_set_regs(client, RTC_CTL2, &value, 1);  mutex_unlock(&hym8563->mutex);rtc_update_irq(hym8563->rtc, 1, RTC_IRQF | RTC_AF | RTC_UF);//printk("%s:irq=%d\n",__func__,irq);return IRQ_HANDLED;
}

enable_irq_wake(hym8563->irq);//时能中断唤醒
我的理解是当我们设好闹钟后,关闭屏幕(休眠),时间到了触发了中断,开屏幕响铃。
详见http://blog.csdn.net/njuitjf/article/details/21475405

rtc=rtc_device_register(client->name, &client->dev,&hym8563_rtc_ops, THIS_MODULE);//向linux系统注册RTC设备,并成生proc、sys目录下的属性文件
详见http://blog.csdn.net/fanqipin/article/details/8089995

HYM8563驱动分析相关推荐

  1. linux串口驱动分析

    linux串口驱动分析 硬件资源及描写叙述 s3c2440A 通用异步接收器和发送器(UART)提供了三个独立的异步串行 I/O(SIO)port,每一个port都能够在中断模式或 DMA 模式下操作 ...

  2. 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息: 内核:linux2.6/linux3.0 系统:android/android4.0  ...

  3. Android10.0 Binder通信原理(五)-Binder驱动分析

    摘要:本节主要来讲解Android10.0 Binder的驱动层分析 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计 ...

  4. linux 串口驱动 atmel_set_mctrl何时调用,linux uart serial使用驱动分析

    uart tty serial 驱动分析 内核版本3.14.23 以atmel为例: 起点: static int __init atmel_serial_init(void) { int ret; ...

  5. linux 网卡驱动分析,LINUX_网卡驱动分析

    LINUX_网卡驱动分析 (36页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.9 积分 Linux DM9000网卡驱动程序完全分析说明仁 本文分 ...

  6. Linux PCI网卡驱动分析

    http://www.uplinux.com/shizi/wenxian/4429.html Linux网卡驱动分析 学习应该是一个先把问题简单化,在把问题复杂化的过程.一开始就着手处理复杂的问题,难 ...

  7. Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇

    Core层中有两个重要函数 mmc_alloc_host 用于构造host,前面已经学习过,这里不再阐述:另一个就是 mmc_add_host,用于注册host 前面探测函数s3cmci_probe, ...

  8. wince串口驱动分析(转)

    wince串口驱动分析 串行通讯接口主要是指UART(通用串行)和IRDA两种.通常的串行连接电气连接上有3wire和9wire两种.3wire的接线方式下定义了发送.接收和地三根连接.其用途就如名称 ...

  9. framebuffer驱动详解4——framebuffer驱动分析2(probe函数讲解)

    以下内容源于朱有鹏<物联网大讲堂>课程的学习,如有侵权,请告知删除. 主要在填充fbdev这个结构体. 二.framebuffer驱动分析2 1.probe函数分析 (1)struct s ...

最新文章

  1. linux locale文件,Linux 怎样修改locale语言设置
  2. 大型银行数据中心用户安全管理
  3. 改善OpenStack上DHCP的性能 【已翻译100%】
  4. 【Unity3D自学记录】判断物体是否在镜头内
  5. smtplib 抄送邮件_用Python收发电子邮件
  6. vue或js解析文件excel表格js通过插件解析表格读取文件
  7. c语言一个数组后添加元素append,jQuery 追加元素、拼接元素的方法总结(append、html、insertBefore、before等)...
  8. git 学习1--查看全局配置
  9. Python 标准库 —— string
  10. 微信小游戏flappy bird填坑
  11. 计算机基本知识(8000)---boot系统引导文件
  12. .net函数查询_SQL窗口函数
  13. Tableau Desktop 2020 Mac支持M1芯片big sur 解决M1芯片安装Tableau闪退问题教程Tableau Public
  14. 平板电脑全国产化电子元件推荐方案
  15. 二手车分析之初步数据分析
  16. 手机图形计算器matlab,Mathlab图形计算器
  17. POJ 有关动态规划的题目
  18. 优派 ELITE XG320Q、XG320U / UG 评测
  19. 5个免费 UI、界面设计素材网
  20. TVS管 与 稳压二极管参数对比

热门文章

  1. Hive时间格式转换
  2. Linux音频驱动之五:UDA1341芯片操作接口
  3. 水木清华站长:水木清华十五年辛酸成败
  4. 济南python中小学试点_山东中小学教师信息技术应用能力提升工程建设全面展开!附试点名单...
  5. 怎么调整照片dpi大小?如何提高图片的dpi分辨率?
  6. python pandas 日期格式_python+pandas+时间、日期以及时间序列处理方法
  7. 【2020模拟赛day6】A. 数字计数
  8. SAP FICO 基础(1)中日双语
  9. Cisdem Unarchiver for Mac(快速解压缩文件)
  10. A记录和CNAME记录的区别