当前位置: 首页 > news >正文

个人主机做网站代运营公司排行榜

个人主机做网站,代运营公司排行榜,赣州做网站,游戏网站规划方案/****************************************************************************** am335x i2c分析* i2c驱动主要关注i2c_algorithm结构体,不同芯片实现自己的master_xfer函数.* 不同芯片i2c驱动框架都类似。* 本文主要描述am335x_i2c设备和驱动的注册…
/******************************************************************************                     am335x i2c分析*  i2c驱动主要关注i2c_algorithm结构体,不同芯片实现自己的master_xfer函数.*  不同芯片i2c驱动框架都类似。*  本文主要描述am335x_i2c设备和驱动的注册,提及文件:*          arch/arm/mach-omap2/board-am335xevm.c*          drivers/i2c/busses/i2c-omap.c*          drivers/i2c/i2c-core.c
*                          Tony Liu, 2016-5-2, Shenzhen  
**************************************************************************
*/ 1. i2c设备注册,配置引脚复用 arch/arm/mach-omap2/board-am335xevm.c MACHINE_START(AM335XEVM, "am335xevm")/* Maintainer: Texas Instruments */.atag_offset = 0x100,.map_io = am335x_evm_map_io,.init_early = am33xx_init_early,.init_irq = ti81xx_init_irq,.handle_irq = omap3_intc_handle_irq,.timer = &omap3_am33xx_timer,.init_machine = am335x_evm_init, MACHINE_ENDstatic void __init am335x_evm_init(void) {am33xx_cpuidle_init();am33xx_mux_init(board_mux);omap_serial_init();am335x_evm_i2c_init(); ---------------------+ //i2c0omap_sdrc_init(NULL, NULL); |usb_musb_init(&musb_board_data); ||omap_board_config = am335x_evm_config; |omap_board_config_size = ARRAY_SIZE(am335x_evm_config); ||daughter_brd_detected = false; |setup_xxx_xxxx(); ---------------|--+ //i2c1, i2c2| |/*create /proc/boardname to export info to userspace*/ | |proc_init(); | || |/* Create an alias for icss clock */ | |if (clk_add_alias("pruss", NULL, "pruss_uart_gclk", NULL)) | |pr_warn("failed to create an alias: icss_uart_gclk --> pruss\n"); | |/* Create an alias for gfx/sgx clock */ | |if (clk_add_alias("sgx_ck", NULL, "gfx_fclk", NULL)) | |pr_warn("failed to create an alias: gfx_fclk --> sgx_ck\n"); | | } | | //初始化i2c 0,由于i2c0引脚的mode0就是i2c功能,所以不需要配置引脚复用 | | static void __init am335x_evm_i2c_init(void) <-------------+ | { |/* Initially assume General Purpose EVM Config */ |am335x_evm_id = EVM_SK; |// i2c 0, speed: 100k |omap_register_i2c_bus(1, 100, i2c0_boardinfo,ARRAY_SIZE(i2c0_boardinfo)); --+ | } | | || | | // i2c设备的设备地址 | | | static struct i2c_board_info i2c0_boardinfo[] = { <-----+ | |{ | |I2C_BOARD_INFO("tps65910", TPS65910_I2C_ID1), | |.platform_data = &am335x_tps65910_info, | |}, | |{ | |I2C_BOARD_INFO("24c02", 0x50), | |}, | | }; | || | int __init omap_register_i2c_bus(int bus_id, u32 clkrate, <----+ |struct i2c_board_info const *info, |unsigned len) | { |int err; ||BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports()); ||if (info) { |err = i2c_register_board_info(bus_id, info, len); |if (err) |return err; |} ||if (!i2c_pdata[bus_id - 1].clkrate) |i2c_pdata[bus_id - 1].clkrate = clkrate; ||i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP; |//注册i2c设备 |return omap_i2c_add_bus(bus_id); | } || static void setup_xxx_xxxx(void) <-------------+ {/*which doesn't have Write Protect pin LAN8710A_PHY_ID */am335x_mmc[0].gpio_wp = -EINVAL;int ret;_configure_device(EVM_SK, xxx_xxxx_dev_cfg, PROFILE_NONE); ---+...... | } || static struct evm_dev_cfg xxx_xxxx_dev_cfg[] = { <--+...... ---+{i2c1_init, DEV_ON_BASEBOARD, PROFILE_ALL}, |{i2c2_init, DEV_ON_BASEBOARD, PROFILE_ALL}, |...... |{NULL, 0, 0}, | }; | //初始化i2c1 | static void i2c1_init(int evm_id, int profile) <----+ {setup_pin_mux(i2c1_pin_mux); //设置i2c引脚复用 -----------+omap_register_i2c_bus(2, 100, am335x_i2c1_boardinfo2,ARRAY_SIZE(am335x_i2c1_boardinfo2));|return; | } || static struct i2c_board_info am335x_i2c1_boardinfo2[] = { |{ |I2C_BOARD_INFO("ds1337", 0x68), |}, |{ |I2C_BOARD_INFO("tlv320aic3x", 0x1b), |}, | }; || static struct pinmux_config i2c1_pin_mux[] = { <-------+{"spi0_d1.i2c1_sda", OMAP_MUX_MODE2 | AM33XX_SLEWCTRL_SLOW |AM33XX_PULL_ENBL | AM33XX_INPUT_EN},{"spi0_cs0.i2c1_scl", OMAP_MUX_MODE2 | AM33XX_SLEWCTRL_SLOW |AM33XX_PULL_ENBL | AM33XX_INPUT_EN},{NULL, 0}, };2. i2c 驱动注册 drivers/i2c/busses/i2c-omap.c static int __init omap_i2c_init_driver(void) {return platform_driver_register(&omap_i2c_driver); -----+ } | subsys_initcall(omap_i2c_init_driver); || static struct platform_driver omap_i2c_driver = { <----+.probe = omap_i2c_probe, -----+.remove = omap_i2c_remove, |.driver = { |.name = "omap_i2c", |.owner = THIS_MODULE, |.pm = OMAP_I2C_PM_OPS, |}, | }; || static int __devinit | omap_i2c_probe(struct platform_device *pdev) <---+ {struct omap_i2c_dev *dev;struct i2c_adapter *adap;struct resource *mem, *irq, *ioarea;struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;irq_handler_t isr;int r;u32 speed = 0;/* NOTE: driver uses the static register mapping */mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (!mem) {dev_err(&pdev->dev, "no mem resource?\n");return -ENODEV;}irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);if (!irq) {dev_err(&pdev->dev, "no irq resource?\n");return -ENODEV;}ioarea = request_mem_region(mem->start, resource_size(mem),pdev->name);if (!ioarea) {dev_err(&pdev->dev, "I2C region already claimed\n");return -EBUSY;}dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);if (!dev) {r = -ENOMEM;goto err_release_region;}if (pdata != NULL) {speed = pdata->clkrate;dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;} else {speed = 100; /* Default speed */dev->set_mpu_wkup_lat = NULL;}dev->speed = speed;dev->dev = &pdev->dev;dev->irq = irq->start;dev->base = ioremap(mem->start, resource_size(mem));if (!dev->base) {r = -ENOMEM;goto err_free_mem;}platform_set_drvdata(pdev, dev);dev->reg_shift = (pdata->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;if (pdata->rev == OMAP_I2C_IP_VERSION_2)dev->regs = (u8 *)reg_map_ip_v2;elsedev->regs = (u8 *)reg_map_ip_v1;pm_runtime_enable(dev->dev);pm_runtime_get_sync(dev->dev);dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;if (dev->rev <= OMAP_I2C_REV_ON_3430)dev->errata |= I2C_OMAP3_1P153;if (!(pdata->flags & OMAP_I2C_FLAG_NO_FIFO)) {u16 s;/* Set up the fifo size - Get total size */s = (omap_i2c_read_reg(dev, OMAP_I2C_BUFSTAT_REG) >> 14) & 0x3;dev->fifo_size = 0x8 << s;/** Set up notification threshold as half the total available* size. This is to ensure that we can handle the status on int* call back latencies.*/dev->fifo_size = (dev->fifo_size / 2);if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)dev->b_hw = 0; /* Disable hardware fixes */elsedev->b_hw = 1; /* Enable hardware fixes *//* calculate wakeup latency constraint for MPU */if (dev->set_mpu_wkup_lat != NULL)dev->latency = (1000000 * dev->fifo_size) /(1000 * speed / 8);}/* reset ASAP, clearing any IRQs */omap_i2c_init(dev);isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :omap_i2c_isr;r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);if (r) {dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);goto err_unuse_clocks;}dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id,pdata->rev, dev->rev >> 4, dev->rev & 0xf, dev->speed);pm_runtime_put(dev->dev);adap = &dev->adapter;i2c_set_adapdata(adap, dev);adap->owner = THIS_MODULE;adap->class = I2C_CLASS_HWMON;strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));adap->algo = &omap_i2c_algo; //i2c发送和接受的算法函数 ------+adap->dev.parent = &pdev->dev; ||/* i2c device drivers may be active on return from add_adapter() */ |adap->nr = pdev->id; |r = i2c_add_numbered_adapter(adap); ----------|--+if (r) { | |dev_err(dev->dev, "failure adding adapter\n"); | |goto err_free_irq; | |} | || |return 0; | || | err_free_irq: | |free_irq(dev->irq, dev); | | err_unuse_clocks: | |omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); | |pm_runtime_put(dev->dev); | |iounmap(dev->base); | | err_free_mem: | |platform_set_drvdata(pdev, NULL); | |kfree(dev); | | err_release_region: | |release_mem_region(mem->start, resource_size(mem)); | || |return r; | | } | || | static const struct i2c_algorithm omap_i2c_algo = { <-----+ |.master_xfer = omap_i2c_xfer, ------+ |.functionality = omap_i2c_func, | | }; | | |V | | omap_i2c_func(struct i2c_adapter *adap) | | { | |return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); | | } | || | static int | | omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) <-+ | { |struct omap_i2c_dev *dev = i2c_get_adapdata(adap); |int i; |int r; ||pm_runtime_get_sync(dev->dev); ||r = omap_i2c_wait_for_bb(dev); |if (r < 0) |goto out; ||if (dev->set_mpu_wkup_lat != NULL) |dev->set_mpu_wkup_lat(dev->dev, dev->latency); ||for (i = 0; i < num; i++) { |r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); -----+ |if (r != 0) | |break; | |} | || |if (dev->set_mpu_wkup_lat != NULL) | |dev->set_mpu_wkup_lat(dev->dev, -1); | || |if (r == 0) | |r = num; | || |omap_i2c_wait_for_bb(dev); | | out: | |pm_runtime_put(dev->dev); | |return r; | | } | || | static int omap_i2c_xfer_msg(struct i2c_adapter *adap, <----+ |struct i2c_msg *msg, int stop) | { |struct omap_i2c_dev *dev = i2c_get_adapdata(adap); |int r; |u16 w; ||dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", |msg->addr, msg->len, msg->flags, stop); ||if (msg->len == 0) |return -EINVAL; |//写设备地址 |omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr); ||/* REVISIT: Could the STB bit of I2C_CON be used with probing? */ |dev->buf = msg->buf; |dev->buf_len = msg->len; |//接受数据的长度 |omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); ||/* Clear the FIFO Buffers */ |w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); |w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; |omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); ||init_completion(&dev->cmd_complete); |dev->cmd_err = 0; ||w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; ||/* High speed configuration */ |if (dev->speed > 400) |w |= OMAP_I2C_CON_OPMODE_HS; ||if (msg->flags & I2C_M_TEN) |w |= OMAP_I2C_CON_XA; |if (!(msg->flags & I2C_M_RD)) |w |= OMAP_I2C_CON_TRX; ||if (!dev->b_hw && stop) |w |= OMAP_I2C_CON_STP; ||omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); ||/* |* Don't write stt and stp together on some hardware. |*/ |if (dev->b_hw && stop) { |unsigned long delay = jiffies + OMAP_I2C_TIMEOUT; |u16 con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); |while (con & OMAP_I2C_CON_STT) { |con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); ||/* Let the user know if i2c is in a bad state */ |if (time_after(jiffies, delay)) { |dev_err(dev->dev, "controller timed out " |"waiting for start condition to finish\n"); |return -ETIMEDOUT; |} |cpu_relax(); |} ||w |= OMAP_I2C_CON_STP; |w &= ~OMAP_I2C_CON_STT; |omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); |} ||/* |* REVISIT: We should abort the transfer on signals, but the bus goes |* into arbitration and we're currently unable to recover from it. |*/ |r = wait_for_completion_timeout(&dev->cmd_complete, |OMAP_I2C_TIMEOUT); |dev->buf_len = 0; |if (r < 0) |return r; |if (r == 0) { |dev_err(dev->dev, "controller timed out\n"); |omap_i2c_init(dev); |return -ETIMEDOUT; |} ||if (likely(!dev->cmd_err)) |return 0; ||/* We have an error */ |if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | |OMAP_I2C_STAT_XUDF)) { |omap_i2c_init(dev); |return -EIO; |} ||if (dev->cmd_err & OMAP_I2C_STAT_NACK) { |if (msg->flags & I2C_M_IGNORE_NAK) |return 0; |if (stop) { |w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); |w |= OMAP_I2C_CON_STP; |omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); |} |return -EREMOTEIO; |} |return -EIO; | } || int i2c_add_numbered_adapter(struct i2c_adapter *adap) <------+ {int id;int status;if (adap->nr == -1) /* -1 means dynamically assign bus id */return i2c_add_adapter(adap);if (adap->nr & ~MAX_ID_MASK)return -EINVAL;retry:if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)return -ENOMEM;mutex_lock(&core_lock);/* "above" here means "above or equal to", sigh;* we need the "equal to" result to force the result*/status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);if (status == 0 && id != adap->nr) {status = -EBUSY;idr_remove(&i2c_adapter_idr, id);}mutex_unlock(&core_lock);if (status == -EAGAIN)goto retry;if (status == 0)status = i2c_register_adapter(adap); ----+return status; | } | EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter); || static int i2c_register_adapter(struct i2c_adapter *adap) <---+ {int res = 0;/* Can't register until after driver model init */if (unlikely(WARN_ON(!i2c_bus_type.p))) {res = -EAGAIN;goto out_list;}/* Sanity checks */if (unlikely(adap->name[0] == '\0')) {pr_err("i2c-core: Attempt to register an adapter with ""no name!\n");return -EINVAL;}if (unlikely(!adap->algo)) {pr_err("i2c-core: Attempt to register adapter '%s' with ""no algo!\n", adap->name);return -EINVAL;}rt_mutex_init(&adap->bus_lock);mutex_init(&adap->userspace_clients_lock);INIT_LIST_HEAD(&adap->userspace_clients);/* Set default timeout to 1 second if not already set */if (adap->timeout == 0)adap->timeout = HZ;dev_set_name(&adap->dev, "i2c-%d", adap->nr); // i2c 设备名adap->dev.bus = &i2c_bus_type;adap->dev.type = &i2c_adapter_type;res = device_register(&adap->dev);if (res)goto out_list;dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);#ifdef CONFIG_I2C_COMPATres = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,adap->dev.parent);if (res)dev_warn(&adap->dev,"Failed to create compatibility class link\n"); #endif/* create pre-declared device nodes */if (adap->nr < __i2c_first_dynamic_bus_num)i2c_scan_static_board_info(adap);/* Notify drivers */mutex_lock(&core_lock);bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);mutex_unlock(&core_lock);return 0;out_list:mutex_lock(&core_lock);idr_remove(&i2c_adapter_idr, adap->nr);mutex_unlock(&core_lock);return res; }

 

http://www.lbrq.cn/news/2457217.html

相关文章:

  • 网站建设微信公众号小程序制作高端网站建设专业公司
  • 轻松做网站自己如何做链接推广
  • 手机开发者选项开启的好还是关闭的好天津seo渠道代理
  • 广州网站排名优化费用网站的营销策略
  • 江苏省建设厅网站公示河北seo
  • 网页制作成app哈尔滨seo关键词排名
  • 厦门网站建设报价seo网站推广专员
  • 大连专业手机自适应网站建设百度seo招聘
  • 网站上的报名表链接是怎么做的链接生成器在线制作
  • 宣传 网站建设方案廊坊seo优化排名
  • 京东商城网站设计网络安全培训
  • 建站宝盒做的网站互联网推广项目
  • 网站建设要花在哪些项目上网络整合营销理论案例
  • 网站恶意做评论万能软文模板
  • 易点科技网站建设本地推广最好用的平台
  • dw怎么做网站跳转今日足球赛事数据
  • 云南网站优化排名网络软文营销
  • 如何添加网站白名单今日新闻最新头条10条摘抄
  • 在手机上做网站是什么软件同城推广引流平台
  • 大学生做外包项目的网站seo排名软件免费
  • 摄影培训网站建设百度推广电话是多少
  • 第一个做装修的网站网络营销有哪些就业岗位
  • 美食网站怎么做美国seo薪酬
  • 十堰seo优化服务长沙关键词优化推荐
  • 湖南网站制作公司乐天seo视频教程
  • j2ee做网站2023年国家免费技能培训
  • 唐卡装饰集团 一站式超级体验店西安关键词优化软件
  • 东川网站制作怎样在百度上发表文章
  • 品牌策划网站建设旺道seo网站优化大师
  • 织梦网站地图生成网络推广员工作内容
  • 4麦 360度定位
  • InfluxDB Line Protocol 协议深度剖析(二)
  • kettle插件-kettle数据挖掘ARFF插件
  • pandas库
  • Unity × RTMP × 头显设备:打造沉浸式工业远控视频系统的完整方案
  • SpringCloud sentinel服务熔断 服务降级