亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? i2c-s3c2410.c

?? 宋寶華的《Linux設備驅動開發詳解》第一版的源代碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
				if (!(iicstat & S3C2410_IICSTAT_BUSBUSY))			return 0;		msleep(1);	}	dev_dbg(i2c->dev, "timeout: GPEDAT is %08x\n",		__raw_readl(S3C2410_GPEDAT));	return -ETIMEDOUT;}/* s3c24xx_i2c_doxfer * * this starts an i2c transfer*/static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int num){	unsigned long timeout;	int ret;	ret = s3c24xx_i2c_set_master(i2c);	if (ret != 0) {		dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);		ret = -EAGAIN;		goto out;	}	spin_lock_irq(&i2c->lock);	i2c->msg     = msgs;	i2c->msg_num = num;	i2c->msg_ptr = 0;	i2c->msg_idx = 0;	i2c->state   = STATE_START;	s3c24xx_i2c_enable_irq(i2c);	s3c24xx_i2c_message_start(i2c, msgs);	spin_unlock_irq(&i2c->lock);		timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);	ret = i2c->msg_idx;	/* having these next two as dev_err() makes life very 	 * noisy when doing an i2cdetect */	if (timeout == 0)		dev_dbg(i2c->dev, "timeout\n");	else if (ret != num)		dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);	/* ensure the stop has been through the bus */	msleep(1); out:	return ret;}/* s3c24xx_i2c_xfer * * first port of call from the i2c bus code when an message needs * transferring across the i2c bus.*/static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,			struct i2c_msg *msgs, int num){	struct s3c24xx_i2c *i2c = (struct s3c24xx_i2c *)adap->algo_data;	int retry;	int ret;	for (retry = 0; retry < adap->retries; retry++) {		ret = s3c24xx_i2c_doxfer(i2c, msgs, num);		if (ret != -EAGAIN)			return ret;		dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);		udelay(100);	}	return -EREMOTEIO;}/* declare our i2c functionality */static u32 s3c24xx_i2c_func(struct i2c_adapter *adap){	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;}/* i2c bus registration info */static struct i2c_algorithm s3c24xx_i2c_algorithm = {	.master_xfer		= s3c24xx_i2c_xfer,	.functionality		= s3c24xx_i2c_func,};static struct s3c24xx_i2c s3c24xx_i2c = {	.lock	= SPIN_LOCK_UNLOCKED,	.wait	= __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),	.adap	= {		.name			= "s3c2410-i2c",		.owner			= THIS_MODULE,		.algo			= &s3c24xx_i2c_algorithm,		.retries		= 2,		.class			= I2C_CLASS_HWMON,	},};/* s3c24xx_i2c_calcdivisor * * return the divisor settings for a given frequency*/static int s3c24xx_i2c_calcdivisor(unsigned long clkin, unsigned int wanted,				   unsigned int *div1, unsigned int *divs){	unsigned int calc_divs = clkin / wanted;	unsigned int calc_div1;	if (calc_divs > (16*16))		calc_div1 = 512;	else		calc_div1 = 16;	calc_divs += calc_div1-1;	calc_divs /= calc_div1;	if (calc_divs == 0)		calc_divs = 1;	if (calc_divs > 17)		calc_divs = 17;	*divs = calc_divs;	*div1 = calc_div1;	return clkin / (calc_divs * calc_div1);}/* freq_acceptable * * test wether a frequency is within the acceptable range of error*/static inline int freq_acceptable(unsigned int freq, unsigned int wanted){	int diff = freq - wanted;	return (diff >= -2 && diff <= 2);}/* s3c24xx_i2c_getdivisor * * work out a divisor for the user requested frequency setting, * either by the requested frequency, or scanning the acceptable * range of frequencies until something is found*/static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,				  struct s3c2410_platform_i2c *pdata,				  unsigned long *iicon,				  unsigned int *got){	unsigned long clkin = clk_get_rate(i2c->clk);		unsigned int divs, div1;	int freq;	int start, end;	clkin /= 1000;		/* clkin now in KHz */     	dev_dbg(i2c->dev,  "pdata %p, freq %lu %lu..%lu\n",		 pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);	if (pdata->bus_freq != 0) {		freq = s3c24xx_i2c_calcdivisor(clkin, pdata->bus_freq/1000,					       &div1, &divs);		if (freq_acceptable(freq, pdata->bus_freq/1000))			goto found;	}	/* ok, we may have to search for something suitable... */	start = (pdata->max_freq == 0) ? pdata->bus_freq : pdata->max_freq;	end = pdata->min_freq;	start /= 1000;	end /= 1000;	/* search loop... */	for (; start > end; start--) {		freq = s3c24xx_i2c_calcdivisor(clkin, start, &div1, &divs);		if (freq_acceptable(freq, start))			goto found;	}	/* cannot find frequency spec */	return -EINVAL; found:	*got = freq;	*iicon |= (divs-1);	*iicon |= (div1 == 512) ? S3C2410_IICCON_TXDIV_512 : 0;	return 0;}/* s3c24xx_i2c_init * * initialise the controller, set the IO lines and frequency */static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c){	unsigned long iicon = S3C2410_IICCON_IRQEN | S3C2410_IICCON_ACKEN;	struct s3c2410_platform_i2c *pdata;	unsigned int freq;	/* get the plafrom data */	pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);	/* inititalise the gpio */	s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_IICSDA);	s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_IICSCL);	/* write slave address */		writeb(pdata->slave_addr, i2c->regs + S3C2410_IICADD);	dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);	/* we need to work out the divisors for the clock... */	if (s3c24xx_i2c_getdivisor(i2c, pdata, &iicon, &freq) != 0) {		dev_err(i2c->dev, "cannot meet bus frequency required\n");		return -EINVAL;	}	/* todo - check that the i2c lines aren't being dragged anywhere */	dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);	dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);		writel(iicon, i2c->regs + S3C2410_IICCON);	/* check for s3c2440 i2c controller  */	if (s3c24xx_i2c_is2440(i2c)) {		dev_dbg(i2c->dev, "S3C2440_IICLC=%08x\n", pdata->sda_delay);		writel(pdata->sda_delay, i2c->regs + S3C2440_IICLC);	}	return 0;}static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c){	if (i2c->clk != NULL && !IS_ERR(i2c->clk)) {		clk_disable(i2c->clk);		clk_put(i2c->clk);		i2c->clk = NULL;	}	if (i2c->regs != NULL) {		iounmap(i2c->regs);		i2c->regs = NULL;	}	if (i2c->ioarea != NULL) {		release_resource(i2c->ioarea);		kfree(i2c->ioarea);		i2c->ioarea = NULL;	}}/* s3c24xx_i2c_probe * * called by the bus driver when a suitable device is found*/static int s3c24xx_i2c_probe(struct platform_device *pdev){	struct s3c24xx_i2c *i2c = &s3c24xx_i2c;	struct resource *res;	int ret;	/* find the clock and enable it */	i2c->dev = &pdev->dev;	i2c->clk = clk_get(&pdev->dev, "i2c");	if (IS_ERR(i2c->clk)) {		dev_err(&pdev->dev, "cannot get clock\n");		ret = -ENOENT;		goto out;	}	dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);	clk_enable(i2c->clk);	/* map the registers */	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	if (res == NULL) {		dev_err(&pdev->dev, "cannot find IO resource\n");		ret = -ENOENT;		goto out;	}	i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1,					 pdev->name);	if (i2c->ioarea == NULL) {		dev_err(&pdev->dev, "cannot request IO\n");		ret = -ENXIO;		goto out;	}	i2c->regs = ioremap(res->start, (res->end-res->start)+1);	if (i2c->regs == NULL) {		dev_err(&pdev->dev, "cannot map IO\n");		ret = -ENXIO;		goto out;	}	dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);	/* setup info block for the i2c core */	i2c->adap.algo_data = i2c;	i2c->adap.dev.parent = &pdev->dev;	/* initialise the i2c controller */	ret = s3c24xx_i2c_init(i2c);	if (ret != 0)		goto out;	/* find the IRQ for this unit (note, this relies on the init call to	 * ensure no current IRQs pending 	 */	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);	if (res == NULL) {		dev_err(&pdev->dev, "cannot find IRQ\n");		ret = -ENOENT;		goto out;	}	ret = request_irq(res->start, s3c24xx_i2c_irq, SA_INTERRUPT,			  pdev->name, i2c);	if (ret != 0) {		dev_err(&pdev->dev, "cannot claim IRQ\n");		goto out;	}	i2c->irq = res;			dev_dbg(&pdev->dev, "irq resource %p (%ld)\n", res, res->start);	ret = i2c_add_adapter(&i2c->adap);	if (ret < 0) {		dev_err(&pdev->dev, "failed to add bus to i2c core\n");		goto out;	}	platform_set_drvdata(pdev, i2c);	dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id); out:	if (ret < 0)		s3c24xx_i2c_free(i2c);	return ret;}/* s3c24xx_i2c_remove * * called when device is removed from the bus*/static int s3c24xx_i2c_remove(struct platform_device *pdev){	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);		if (i2c != NULL) {		s3c24xx_i2c_free(i2c);		platform_set_drvdata(pdev, NULL);	}	return 0;}#ifdef CONFIG_PMstatic int s3c24xx_i2c_resume(struct platform_device *dev){	struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);	if (i2c != NULL)		s3c24xx_i2c_init(i2c);	return 0;}#else#define s3c24xx_i2c_resume NULL#endif/* device driver for platform bus bits */static struct platform_driver s3c2410_i2c_driver = {	.probe		= s3c24xx_i2c_probe,	.remove		= s3c24xx_i2c_remove,	.resume		= s3c24xx_i2c_resume,	.driver		= {		.owner	= THIS_MODULE,		.name	= "s3c2410-i2c",	},};static struct platform_driver s3c2440_i2c_driver = {	.probe		= s3c24xx_i2c_probe,	.remove		= s3c24xx_i2c_remove,	.resume		= s3c24xx_i2c_resume,	.driver		= {		.owner	= THIS_MODULE,		.name	= "s3c2440-i2c",	},};static int __init i2c_adap_s3c_init(void){	int ret;	ret = platform_driver_register(&s3c2410_i2c_driver);	if (ret == 0) {		ret = platform_driver_register(&s3c2440_i2c_driver);		if (ret)			platform_driver_unregister(&s3c2410_i2c_driver);	}	return ret;}static void __exit i2c_adap_s3c_exit(void){	platform_driver_unregister(&s3c2410_i2c_driver);	platform_driver_unregister(&s3c2440_i2c_driver);}module_init(i2c_adap_s3c_init);module_exit(i2c_adap_s3c_exit);MODULE_DESCRIPTION("S3C24XX I2C Bus driver");MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");MODULE_LICENSE("GPL");

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩—二三区免费观看av| 一区二区三区四区五区视频在线观看| 欧美精品一区二区久久久| 国产精品毛片无遮挡高清| 日本中文字幕一区| 91碰在线视频| 亚洲国产精品精华液ab| 首页综合国产亚洲丝袜| 91在线丨porny丨国产| 国产日产精品1区| 美腿丝袜在线亚洲一区| 欧美乱熟臀69xxxxxx| 亚洲欧美影音先锋| 成人性视频网站| 国产偷v国产偷v亚洲高清| 日本伊人午夜精品| 欧美精品日韩精品| 一区二区免费看| 91婷婷韩国欧美一区二区| 国产精品视频看| 国产aⅴ精品一区二区三区色成熟| 欧美一区二区国产| 天堂成人国产精品一区| 欧美日韩在线一区二区| 天堂影院一区二区| 91国产免费观看| 日韩毛片视频在线看| 不卡的看片网站| 成人免费在线播放视频| 成人免费av资源| 中文字幕的久久| 波多野结衣欧美| **网站欧美大片在线观看| 国产精品99久久久久久似苏梦涵 | 久久丝袜美腿综合| 久久成人久久爱| 亚洲精品在线免费观看视频| 日本 国产 欧美色综合| 精品久久久久一区| 国产一区二区在线观看视频| 久久蜜桃av一区二区天堂| 国产一区二区女| 国产日韩av一区| 99久久er热在这里只有精品66| 中文字幕日本不卡| 欧美少妇bbb| 美女在线一区二区| 久久精品视频一区二区三区| 国产乱一区二区| 中文字幕日韩av资源站| 欧美日韩国产成人在线91| 秋霞影院一区二区| 国产日韩成人精品| 欧洲色大大久久| 精品一区二区三区蜜桃| 欧美韩日一区二区三区| 91精品福利视频| 蜜臀av性久久久久av蜜臀妖精| 久久久久久久综合日本| 91丨porny丨中文| 亚洲第一成人在线| 26uuuu精品一区二区| 99久久精品国产毛片| 日本欧美加勒比视频| 国产亚洲美州欧州综合国| 91一区二区在线| 免费成人美女在线观看.| 国产三级精品三级在线专区| 欧美亚洲愉拍一区二区| 盗摄精品av一区二区三区| 亚洲欧美激情一区二区| 日韩视频一区二区| 91小宝寻花一区二区三区| 日本视频中文字幕一区二区三区| 国产午夜精品久久久久久久| 欧美在线三级电影| 国产精品夜夜嗨| 午夜私人影院久久久久| 国产精品国模大尺度视频| 欧美一二三区在线观看| 色综合色狠狠天天综合色| 国产在线不卡一卡二卡三卡四卡| 亚洲精品中文字幕在线观看| 2023国产精品自拍| 欧美精品18+| 91首页免费视频| 国产一区二区在线电影| 日本在线播放一区二区三区| 亚洲免费高清视频在线| 国产午夜精品久久久久久免费视| 在线播放视频一区| 在线免费观看一区| 国产91清纯白嫩初高中在线观看 | 亚洲色图制服丝袜| 久久亚洲一区二区三区四区| 91国偷自产一区二区开放时间| 国产酒店精品激情| 蜜臀久久久99精品久久久久久| 一区二区三区在线视频免费观看| 欧美激情一二三区| 久久精品亚洲一区二区三区浴池| 欧美人xxxx| 欧美精品一区二区三区一线天视频| 欧美午夜精品久久久久久孕妇| www.综合网.com| 成人精品一区二区三区四区| 国产精品一区二区视频| 黄色小说综合网站| 韩国一区二区在线观看| 久久99国产精品久久99| 国模少妇一区二区三区| 久久国产人妖系列| 精品一二线国产| 韩国一区二区在线观看| 国产福利91精品一区二区三区| 另类人妖一区二区av| 日本最新不卡在线| 五月天婷婷综合| 五月婷婷激情综合| 欧美aⅴ一区二区三区视频| 麻豆久久久久久| 国产一区二区h| 成人美女在线视频| 99久久99久久精品免费观看| 99re8在线精品视频免费播放| 91蝌蚪国产九色| 欧美伊人久久久久久久久影院| 欧美在线观看18| 欧美电影在哪看比较好| 欧美一级精品大片| 久久精品水蜜桃av综合天堂| 国产精品视频九色porn| 亚洲综合色视频| 麻豆精品蜜桃视频网站| 国产一区 二区| 成人激情黄色小说| 91精彩视频在线| 日韩欧美一级特黄在线播放| 久久蜜桃香蕉精品一区二区三区| 国产精品久久综合| 午夜成人在线视频| 国产精品99久久久久久久女警 | 欧美无人高清视频在线观看| 欧美卡1卡2卡| 久久综合五月天婷婷伊人| 国产精品欧美一区喷水| 亚洲线精品一区二区三区八戒| 久久精品国产精品亚洲精品| av网站一区二区三区| 欧美精品一二三四| 欧美国产成人精品| 亚洲福利视频导航| 大胆欧美人体老妇| 欧美精品日韩综合在线| 国产视频一区二区在线| 亚洲制服丝袜av| 国产精品1区2区| 欧美日本一区二区三区四区| 久久久99久久精品欧美| 亚洲国产一区二区在线播放| 国产一区二三区| 欧美日韩成人一区| 久久精品夜色噜噜亚洲a∨| 亚洲成人手机在线| 国产成都精品91一区二区三| 欧美日韩大陆在线| 亚洲色图丝袜美腿| 国产成人自拍网| 91精品国产色综合久久ai换脸| 亚洲少妇30p| 国产精品羞羞答答xxdd| 91精品国产福利| 亚洲一区二区三区四区在线免费观看 | 欧美性大战久久久久久久蜜臀 | 日韩欧美aaaaaa| 亚洲欧美乱综合| 成人久久18免费网站麻豆| 日韩欧美一区二区视频| 亚洲动漫第一页| 色婷婷av一区二区三区gif| 久久久精品天堂| 美女任你摸久久| 欧美日韩中文字幕一区二区| 中文字幕日本不卡| av成人老司机| 国产日韩精品一区二区三区 | 精品国产一区二区亚洲人成毛片| 亚洲欧美国产三级| 99精品一区二区三区| 国产精品欧美精品| 国产盗摄一区二区三区| 国产亚洲精品久| 国产不卡免费视频| 欧美高清在线视频| 国产成人在线视频免费播放| 亚洲精品一区二区在线观看| 极品少妇xxxx精品少妇| 精品欧美乱码久久久久久1区2区| 免费在线看成人av| 精品国产乱子伦一区|