static void dummy_codec_device_init(void) { #ifdef CONFIG_USE_OF int ret; struct pinctrl_state *s; p = pinctrl_get(dummy_codec_dev); if (IS_ERR(p)) return; s = pinctrl_lookup_state(p, "dummy_codec_audio"); if (IS_ERR(s)) { pinctrl_put(p); return; } ret = pinctrl_select_state(p, s); if (ret < 0) { pinctrl_put(p); return; } printk("=%s==,dummy_codec_audio init done\n",__func__); #else /* audio pinmux */ // pinmux_set(&rt5631_pinmux_set); /* GPIOA_19 PULL_UP_REG0 bit19 */ // aml_set_reg32_bits(P_PAD_PULL_UP_REG0, 1, 19, 1); #endif }
static void dummy_codec_device_deinit(void) { #ifdef CONFIG_USE_OF pinctrl_put(p); #else // pinmux_clr(&rt5631_pinmux_set); #endif }
static int sirfsoc_uart_remove(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); struct uart_port *port = &sirfport->port; platform_set_drvdata(pdev, NULL); if (sirfport->hw_flow_ctrl) pinctrl_put(sirfport->p); uart_remove_one_port(&sirfsoc_uart_drv, port); return 0; }
static int __devexit spi_sirfsoc_remove(struct platform_device *pdev) { struct spi_master *master; struct sirfsoc_spi *sspi; int i; master = platform_get_drvdata(pdev); sspi = spi_master_get_devdata(master); spi_bitbang_stop(&sspi->bitbang); for (i = 0; i < master->num_chipselect; i++) { if (sspi->chipselect[i] > 0) gpio_free(sspi->chipselect[i]); } clk_disable_unprepare(sspi->clk); clk_put(sspi->clk); pinctrl_put(sspi->p); spi_master_put(master); return 0; }
static int hi6401_irq_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct hi6401_irq *irq = platform_get_drvdata(pdev); if(irq->pll_delay_wq) { cancel_delayed_work(&irq->pll_delay_work); flush_workqueue(irq->pll_delay_wq); destroy_workqueue(irq->pll_delay_wq); } if(irq->hi6401_irq_delay_wq) { cancel_delayed_work(&irq->hi6401_irq_delay_work); flush_workqueue(irq->hi6401_irq_delay_wq); destroy_workqueue(irq->hi6401_irq_delay_wq); } free_irq(irq->irq, irq); gpio_free(irq->gpio); clk_disable_unprepare(irq->pmu_audio_clk); devm_clk_put(dev, irq->pmu_audio_clk); clk_disable_unprepare(irq->codec_ssi_clk); devm_clk_put(dev, irq->codec_ssi_clk); codec_ssi_iomux_idle(irq->pctrl); pinctrl_put(irq->pctrl); devm_iounmap(dev, irq->reg_base_addr); devm_release_mem_region(dev, irq->res->start, resource_size(irq->res)); devm_kfree(dev, irq); platform_set_drvdata(pdev, NULL); if (g_dump_buf) { kfree(g_dump_buf); g_dump_buf = NULL; } return 0; }
static int __devinit spi_sirfsoc_probe(struct platform_device *pdev) { struct sirfsoc_spi *sspi; struct spi_master *master; struct resource *mem_res; int num_cs, cs_gpio, irq; int i; int ret; ret = of_property_read_u32(pdev->dev.of_node, "sirf,spi-num-chipselects", &num_cs); if (ret < 0) { dev_err(&pdev->dev, "Unable to get chip select number\n"); goto err_cs; } master = spi_alloc_master(&pdev->dev, sizeof(*sspi) + sizeof(int) * num_cs); if (!master) { dev_err(&pdev->dev, "Unable to allocate SPI master\n"); return -ENOMEM; } platform_set_drvdata(pdev, master); sspi = spi_master_get_devdata(master); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { dev_err(&pdev->dev, "Unable to get IO resource\n"); ret = -ENODEV; goto free_master; } master->num_chipselect = num_cs; for (i = 0; i < master->num_chipselect; i++) { cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", i); if (cs_gpio < 0) { dev_err(&pdev->dev, "can't get cs gpio from DT\n"); ret = -ENODEV; goto free_master; } sspi->chipselect[i] = cs_gpio; if (cs_gpio == 0) continue; /* use cs from spi controller */ ret = gpio_request(cs_gpio, DRIVER_NAME); if (ret) { while (i > 0) { i--; if (sspi->chipselect[i] > 0) gpio_free(sspi->chipselect[i]); } dev_err(&pdev->dev, "fail to request cs gpios\n"); goto free_master; } } sspi->base = devm_ioremap_resource(&pdev->dev, mem_res); if (IS_ERR(sspi->base)) { ret = PTR_ERR(sspi->base); goto free_master; } irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENXIO; goto free_master; } ret = devm_request_irq(&pdev->dev, irq, spi_sirfsoc_irq, 0, DRIVER_NAME, sspi); if (ret) goto free_master; sspi->bitbang.master = spi_master_get(master); sspi->bitbang.chipselect = spi_sirfsoc_chipselect; sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer; sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer; sspi->bitbang.master->setup = spi_sirfsoc_setup; master->bus_num = pdev->id; sspi->bitbang.master->dev.of_node = pdev->dev.of_node; sspi->p = pinctrl_get_select_default(&pdev->dev); ret = IS_ERR(sspi->p); if (ret) goto free_master; sspi->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(sspi->clk)) { ret = -EINVAL; goto free_pin; } clk_prepare_enable(sspi->clk); sspi->ctrl_freq = clk_get_rate(sspi->clk); init_completion(&sspi->done); tasklet_init(&sspi->tasklet_tx, spi_sirfsoc_tasklet_tx, (unsigned long)sspi); writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP); writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP); writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP); writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_TXFIFO_OP); /* We are not using dummy delay between command and data */ writel(0, sspi->base + SIRFSOC_SPI_DUMMY_DELAY_CTL); ret = spi_bitbang_start(&sspi->bitbang); if (ret) goto free_clk; dev_info(&pdev->dev, "registerred, bus number = %d\n", master->bus_num); return 0; free_clk: clk_disable_unprepare(sspi->clk); clk_put(sspi->clk); free_pin: pinctrl_put(sspi->p); free_master: spi_master_put(master); err_cs: return ret; }
int sirfsoc_uart_probe(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport; struct uart_port *port; struct resource *res; int ret; if (of_property_read_u32(pdev->dev.of_node, "cell-index", &pdev->id)) { dev_err(&pdev->dev, "Unable to find cell-index in uart node.\n"); ret = -EFAULT; goto err; } sirfport = &sirfsoc_uart_ports[pdev->id]; port = &sirfport->port; port->dev = &pdev->dev; port->private_data = sirfport; if (of_find_property(pdev->dev.of_node, "hw_flow_ctrl", NULL)) sirfport->hw_flow_ctrl = 1; if (of_property_read_u32(pdev->dev.of_node, "fifosize", &port->fifosize)) { dev_err(&pdev->dev, "Unable to find fifosize in uart node.\n"); ret = -EFAULT; goto err; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } port->mapbase = res->start; port->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!port->membase) { dev_err(&pdev->dev, "Cannot remap resource.\n"); ret = -ENOMEM; goto err; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "Insufficient resources.\n"); ret = -EFAULT; goto err; } port->irq = res->start; if (sirfport->hw_flow_ctrl) { sirfport->p = pinctrl_get_select_default(&pdev->dev); if (IS_ERR(sirfport->p)) { ret = PTR_ERR(sirfport->p); goto err; } } sirfport->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(sirfport->clk)) { ret = PTR_ERR(sirfport->clk); goto clk_err; } clk_prepare_enable(sirfport->clk); port->uartclk = clk_get_rate(sirfport->clk); port->ops = &sirfsoc_uart_ops; spin_lock_init(&port->lock); platform_set_drvdata(pdev, sirfport); ret = uart_add_one_port(&sirfsoc_uart_drv, port); if (ret != 0) { dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); goto port_err; } return 0; port_err: clk_disable_unprepare(sirfport->clk); clk_put(sirfport->clk); clk_err: platform_set_drvdata(pdev, NULL); if (sirfport->hw_flow_ctrl) pinctrl_put(sirfport->p); err: return ret; }
int pinctrl_cmds_tx(struct platform_device *pdev, struct pinctrl_cmd_desc *cmds, int cnt) { int ret = 0; int i = 0; struct pinctrl_cmd_desc *cm = NULL; cm = cmds; for(i = 0; i < cnt; i++) { if(cm == NULL) { HISI_FB_ERR("command %d is null!\n", i); continue; } if(cm->dtype == DTYPE_PINCTRL_GET) { cm->pctrl_data->p = devm_pinctrl_get(&pdev->dev); } else if(cm->dtype == DTYPE_PINCTRL_STATE_GET) { /* check pinctrl pointer*/ // TO BE DONE if(cm ->mode == DTYPE_PINCTRL_STATE_DEFAULT) { cm->pctrl_data->pinctrl_def = pinctrl_lookup_state(cm->pctrl_data->p,PINCTRL_STATE_DEFAULT); } else if(cm ->mode == DTYPE_PINCTRL_STATE_IDLE) { cm->pctrl_data->pinctrl_idle = pinctrl_lookup_state(cm->pctrl_data->p,PINCTRL_STATE_IDLE); } else { ret = -1; HISI_FB_ERR("unknown pinctrl type to get!\n"); goto err; } } else if(cm->dtype == DTYPE_PINCTRL_SET) { /* check pinctrl pointer*/ // TO BE DONE if(cm ->mode == DTYPE_PINCTRL_STATE_DEFAULT) { /* check pinctrl_def pointer*/ // TO BE DONE ret = pinctrl_select_state(cm->pctrl_data->p, cm->pctrl_data->pinctrl_def); if(ret) { HISI_FB_ERR("could not set this pin to default state!\n"); ret = -1; goto err; } } else if(cm ->mode == DTYPE_PINCTRL_STATE_IDLE) { /* check pinctrl_def pointer*/ // TO BE DONE ret = pinctrl_select_state(cm->pctrl_data->p, cm->pctrl_data->pinctrl_idle); if(ret) { HISI_FB_ERR("could not set this pin to idle state!\n"); ret = -1; goto err; } } else { ret = -1; HISI_FB_ERR("unknown pinctrl type to set!\n"); goto err; } } else if(cm->dtype == DTYPE_PINCTRL_PUT) { pinctrl_put(cm->pctrl_data->p); } else { HISI_FB_ERR("not supported command type!\n"); ret = -1; goto err; } cm++; } return ret; err: return ret; }
static int k3_gps_bcm_probe(struct platform_device* pdev) { GPS_BCM_INFO* gps_bcm = NULL; struct device* gps_power_dev = &pdev->dev; struct device_node* np = gps_power_dev->of_node; int ret = 0; int irq = 0; struct gps_geofence_wake* ac_data = &g_geofence_wake; printk(KERN_INFO "[GPS] start find gps_power and ic type is 4774\n"); gps_bcm = kzalloc(sizeof(GPS_BCM_INFO), GFP_KERNEL); if (!gps_bcm) { printk(KERN_ERR "[GPS] Alloc memory failed\n"); return -ENOMEM; } gps_dir = proc_mkdir("gps", NULL); if (!gps_dir) { printk(KERN_ERR "[GPS] proc dir create failed\n"); ret = -ENOMEM; goto err_free_gps; } ret = gps_bcm4774_node_init(np, &gps_bcm->gpioid_en, GPS_PROC_EN, &gps_proc_fops_nstandby); if (0 != ret) { printk(KERN_ERR "[GPS] gps_bcm4774_node_init gps_bcm failed.\n"); ret = -1; goto err_free_nstandby; } gps_bcm->gpioid_hostwake.gpio = of_get_named_gpio(np, "huawei,gps_hostwake", 0); if (!gpio_is_valid(gps_bcm->gpioid_hostwake.gpio)) { ret = -1; printk(KERN_ERR "[GPS] get huawei,gps_hostwake failed.\n"); goto err_free_gps_en; } // 1. Init GPIO and IRQ for HOST_WAKE printk("[gps]%s,gps_bcm->gpioid_hostwake.gpio=%d\n", __func__, gps_bcm->gpioid_hostwake.gpio); // 2. Register Driver memset(ac_data, 0, sizeof(struct gps_geofence_wake)); // 2.1 Misc device setup ac_data->misc.minor = MISC_DYNAMIC_MINOR; ac_data->misc.name = HOST_WAKE_MODULE_NAME; ac_data->misc.fops = &gps_geofence_wake_fops; // 2.2 Information that be used later ac_data->irq = irq; ac_data->host_req_pin = gps_bcm->gpioid_hostwake.gpio; printk("[gps]misc register, name %s, irq %d, host req pin num %d\n", ac_data->misc.name, irq, ac_data->host_req_pin); // 2.3 Register misc driver if (0 != (ret = misc_register(&ac_data->misc))) { printk("[gps]cannot register gps geofence wake miscdev on minor=%d (%d)\n", MISC_DYNAMIC_MINOR, ret); goto err_free_host_wake; } // 3. Init wake_lock wake_lock_init(&ac_data->wake_lock, WAKE_LOCK_SUSPEND, "gps_geofence_wakelock"); printk("[gps]wake_lock_init done\n"); irq = gps_gpio_irq_init(gps_bcm->gpioid_hostwake.gpio); if (irq < 0) { printk("[gps]hostwake irq error\n"); goto err_free_misc_register; } /* Set 32KC clock */ gps_bcm->clk = of_clk_get_by_name(np, "gps_32k"); if (IS_ERR(gps_bcm->clk)) { printk(KERN_ERR "[GPS] clk_32k get failed!\n"); ret = -1; goto err_free_misc_register; } ret = clk_prepare_enable(gps_bcm->clk); if (ret) { printk(KERN_ERR "[GPS] clk_32k enable is failed\n"); goto err_free_clk; } printk(KERN_INFO "[GPS] clk_32k is finished\n"); ret = gps_bcm4774_node_init(np, &gps_bcm->mcu_req, GPS_PROC_MCUREQ, &gps_proc_fops_mcureq); if (0 != ret) { printk(KERN_ERR "[GPS]gps_bcm4774_node_init mcu_req failed \n"); goto err_free_mcureq; } ret = gps_bcm4774_node_init(np, &gps_bcm->mcu_req_rsp, GPS_PROC_MCUREQ_RSP, &gps_proc_fops_mcureq_rsp); if (0 != ret) { printk(KERN_ERR "[GPS]gps_bcm4774_node_init mcu_req_rsp failed \n"); goto err_free_mcureq_rsp; } gps_bcm->pctrl = devm_pinctrl_get(gps_power_dev); if (IS_ERR(gps_bcm->pctrl)) { printk(KERN_ERR "[GPS] pinctrl get error!\n"); ret = -1; goto err_free_clk; } gps_bcm->pins_normal = pinctrl_lookup_state(gps_bcm->pctrl, "default"); if (IS_ERR(gps_bcm->pins_normal)) { printk(KERN_ERR "[GPS] gps_bcm->pins_normal lookup error!\n"); ret = -1; goto err_free_pinctrl; } gps_bcm->pins_idle = pinctrl_lookup_state(gps_bcm->pctrl, "idle"); if (IS_ERR(gps_bcm->pins_idle)) { printk(KERN_ERR "[GPS] gps_bcm->pins_idle lookup error!\n"); ret = -1; goto err_free_pinctrl; } ret = pinctrl_select_state(gps_bcm->pctrl, gps_bcm->pins_normal); if (ret) { printk(KERN_ERR "[GPS] pinctrl_select_state error!\n"); goto err_free_pinctrl; } printk(KERN_INFO "[GPS] pinctrl is finish\n"); gps_bcm->refclk = of_clk_get_by_name(np, "clk_gps"); if (IS_ERR(gps_bcm->refclk)) { printk(KERN_ERR "[GPS] @@@ref_clk get failed!\n"); ret = -1; goto err_free_pinctrl; } ret = clk_set_rate(gps_bcm->refclk , GPS_REF_CLK_FREQ_19M); if (ret < 0) { printk(KERN_ERR "[GPS] clk_set_rate HI3635_CLK_RATE failed\n"); goto err_free_refclk; } gps_ref_clk = gps_bcm->refclk; printk(KERN_INFO "[GPS] ref clk is finished!\n"); platform_set_drvdata(pdev, gps_bcm); g_gps_bcm = gps_bcm; return 0; err_free_refclk: clk_put(gps_bcm->refclk); err_free_pinctrl: pinctrl_put(gps_bcm->pctrl); err_free_mcureq: err_free_mcureq_rsp: err_free_clk: clk_put(gps_bcm->clk); err_free_misc_register: misc_deregister(&ac_data->misc); wake_lock_destroy(&ac_data->wake_lock); pr_err("%s: misc_deregister!\n", __func__); err_free_host_wake: gpio_free(gps_bcm->gpioid_hostwake.gpio); pr_err("%s: err_free_host_wake!\n", __func__); err_free_gps_en: gpio_free(gps_bcm->gpioid_en.gpio); err_free_nstandby: err_free_gps: kfree(gps_bcm); gps_bcm = NULL; g_gps_bcm = NULL; return ret; }
static int cw_bat_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct cw_bat_platform_data *pdata = client->dev.platform_data; struct cw_battery *cw_bat; int ret; int loop = 0; printk("\ncw2015/cw2013 driver v1.2 probe start, battery_type_id is %d\n", battery_type_id); cw_bat = kzalloc(sizeof(struct cw_battery), GFP_KERNEL); if (!cw_bat) { dev_err(&cw_bat->client->dev, "fail to allocate memory\n"); return -ENOMEM; } if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(struct cw_bat_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "GTP Failed to allocate memory for pdata\n"); return -ENOMEM; } ret = cw_bat_parse_dt(&client->dev, pdata); if (ret) return ret; } else { pdata = client->dev.platform_data; } if (!pdata) { dev_err(&client->dev, "Invalid pdata\n"); return -EINVAL; } if (battery_type_id == 0) { pdata->cw_bat_config_info = config_info_desai ; } else if (battery_type_id == 1) { pdata->cw_bat_config_info = config_info_feimaotui ; } else if (battery_type_id == 2) { pdata->cw_bat_config_info = config_info_guanyu ; } else if (battery_type_id == 3) { pdata->cw_bat_config_info = config_info_xinwangda; } else { pdata->cw_bat_config_info = config_info; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "I2C not supported\n"); return -ENODEV; } cw_bat->client = client; i2c_set_clientdata(client, cw_bat); cw_bat->plat_data = pdata; ret = cw_check_ic(cw_bat); while ((loop++ < 5) && (ret != 0)) { pr_debug(" check ret is %d, loop is %d \n" , ret, loop); ret = cw_check_ic(cw_bat); } if (ret != 0) { pr_debug(" wc_check_ic fail , return ENODEV \n"); return -ENODEV; } ret = cw_init(cw_bat); while ((loop++ < 2000) && (ret != 0)) { ret = cw_init(cw_bat); } if (ret) { return ret; } cw_bat->rk_bat.name = "rk-bat"; cw_bat->rk_bat.type = POWER_SUPPLY_TYPE_BATTERY; cw_bat->rk_bat.properties = rk_battery_properties; cw_bat->rk_bat.num_properties = ARRAY_SIZE(rk_battery_properties); cw_bat->rk_bat.get_property = rk_battery_get_property; ret = power_supply_register(&client->dev, &cw_bat->rk_bat); if (ret < 0) { dev_err(&cw_bat->client->dev, "power supply register rk_bat error\n"); printk("rk_bat_register_fail\n"); goto rk_bat_register_fail; } cw_bat->charger_mode = 0; cw_bat->capacity = 0; cw_bat->voltage = 0; cw_bat->status = 0; cw_bat->time_to_empty = 0; cw_bat->bat_change = 0; cw_update_time_member_capacity_change(cw_bat); cw_update_time_member_charge_start(cw_bat); cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery"); INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work); queue_delayed_work(cw_bat->battery_workqueue, &cw_bat->battery_delay_work, msecs_to_jiffies(10)); #ifdef BAT_LOW_INTERRUPT ret = cw_bat_regulator_configure(cw_bat, true); if (ret < 0) { dev_err(&client->dev, "%s Failed to configure regulators\n", __func__); goto err_reg_configure; } ret = cw_bat_power_on(cw_bat, true); if (ret < 0) { dev_err(&client->dev, "%s Failed to power on\n", __func__); goto err_power_device; } ret = cw_bat_pinctrl_init(cw_bat); if (!ret && cw_bat->ts_pinctrl) { ret = pinctrl_select_state(cw_bat->ts_pinctrl, cw_bat->pinctrl_state_active); if (ret < 0) goto err_pinctrl_select; } ret = cw_bat_gpio_configure(cw_bat, true); if (ret < 0) { dev_err(&client->dev, "%s Failed to configure gpios\n", __func__); goto err_gpio_config; } INIT_DELAYED_WORK(&cw_bat->bat_low_wakeup_work, bat_low_detect_do_wakeup); wake_lock_init(&bat_low_wakelock, WAKE_LOCK_SUSPEND, "bat_low_detect"); cw_bat->client->irq = gpio_to_irq(pdata->bat_low_pin); ret = request_threaded_irq(client->irq, NULL, bat_low_detect_irq_handler, pdata->irq_flags, "bat_low_detect", cw_bat); if (ret) { dev_err(&client->dev, "request irq failed\n"); gpio_free(cw_bat->plat_data->bat_low_pin); } /*Chaman add for charger detect*/ charge_psy = power_supply_get_by_name("usb"); err_gpio_config: if (cw_bat->ts_pinctrl) { ret = cw_bat_pinctrl_select(cw_bat, false); if (ret < 0) pr_err("Cannot get idle pinctrl state\n"); } err_pinctrl_select: if (cw_bat->ts_pinctrl) { pinctrl_put(cw_bat->ts_pinctrl); } err_power_device: cw_bat_power_on(cw_bat, false); err_reg_configure: cw_bat_regulator_configure(cw_bat, false); #endif printk("\ncw2015/cw2013 driver v1.2 probe sucess\n"); return 0; rk_bat_register_fail: dev_dbg(&cw_bat->client->dev, "cw2015/cw2013 driver v1.2 probe error!!!!\n"); return ret; }
static int hi6401_irq_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct hi6401_irq *irq = NULL; enum of_gpio_flags flags; unsigned int virq; int ret = 0; int i; irq = devm_kzalloc(dev, sizeof(*irq), GFP_KERNEL); if (!irq) { dev_err(dev, "cannot allocate hi6401_irq device info\n"); return -ENOMEM; } platform_set_drvdata(pdev, irq); /* get resources */ irq->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!irq->res) { dev_err(dev, "platform_get_resource err\n"); goto err_exit; } if (!devm_request_mem_region(dev, irq->res->start, resource_size(irq->res), pdev->name)) { dev_err(dev, "cannot claim register memory\n"); goto err_exit; } irq->reg_base_addr = devm_ioremap(dev, irq->res->start, resource_size(irq->res)); if (!irq->reg_base_addr) { dev_err(dev, "cannot map register memory\n"); goto ioremap_err; } /* get pinctrl */ irq->pctrl = devm_pinctrl_get(dev); if (IS_ERR(irq->pctrl)) { dev_err(dev, "could not get pinctrl\n"); goto codec_ssi_get_err; } ret = codec_ssi_iomux_default(irq->pctrl); if (0 != ret) goto codec_ssi_iomux_err; /* get codec ssi clk */ irq->codec_ssi_clk = devm_clk_get(dev, "clk_codecssi"); if (IS_ERR(irq->codec_ssi_clk)) { pr_err("clk_get: codecssi clk not found!\n"); ret = PTR_ERR(irq->codec_ssi_clk); goto codec_ssi_clk_err; } ret = clk_prepare_enable(irq->codec_ssi_clk); if (0 != ret) { pr_err("codec_ssi_clk :clk prepare enable failed !\n"); goto codec_ssi_clk_enable_err; } /* get pmu audio clk */ irq->pmu_audio_clk = devm_clk_get(dev, "clk_pmuaudioclk"); if (IS_ERR(irq->pmu_audio_clk)) { pr_err("_clk_get: pmu_audio_clk not found!\n"); ret = PTR_ERR(irq->pmu_audio_clk); goto pmu_audio_clk_err; } ret = clk_prepare_enable(irq->pmu_audio_clk); if (0 != ret) { pr_err("pmu_audio_clk :clk prepare enable failed !\n"); goto pmu_audio_clk_enable_err; } spin_lock_init(&irq->lock); spin_lock_init(&irq->rw_lock); mutex_init(&irq->sr_mutex); mutex_init(&irq->pll_mutex); wake_lock_init(&irq->wake_lock, WAKE_LOCK_SUSPEND, "hi6401-irq"); irq->dev = dev; /* clear IRQ status */ hi6401_irq_write(irq, HI6401_REG_IRQ_0, 0xFF); hi6401_irq_write(irq, HI6401_REG_IRQ_1, 0xFF); /* mask all irqs */ hi6401_irq_write(irq, HI6401_REG_IRQM_0, 0xFF); hi6401_irq_write(irq, HI6401_REG_IRQM_1, 0xFF); irq->gpio = of_get_gpio_flags(np, 0, &flags); if (0 > irq->gpio) { dev_err(dev, "get gpio flags error\n"); ret = irq->gpio; goto get_gpio_err; } if (!gpio_is_valid(irq->gpio)) { dev_err(dev, "gpio is invalid\n"); ret = -EINVAL; goto get_gpio_err; } ret = gpio_request_one(irq->gpio, GPIOF_IN, "hi6401_irq"); if (0 > ret) { dev_err(dev, "failed to request gpio%d\n", irq->gpio); goto get_gpio_err; } irq->irq = gpio_to_irq(irq->gpio); irq->domain = irq_domain_add_simple(np, HI6401_MAX_IRQS, 0, &hi6401_domain_ops, irq); if (!irq->domain) { dev_err(dev, "irq domain error\n"); ret = -ENODEV; goto gpio_err; } for (i = 0; i < HI6401_MAX_IRQS; i++) { virq = irq_create_mapping(irq->domain, i); if (virq == NO_IRQ) { dev_err(dev, "Failed mapping hwirq\n"); ret = -ENOSPC; goto gpio_err; } irq->irqs[i] = virq; } ret = request_irq(irq->irq, hi6401_irq_handler, IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, "hi6401_irq", irq); if (0 > ret) { dev_err(dev, "could not claim irq %d\n", ret); ret = -ENODEV; goto gpio_err; } irq->hi6401_irq_delay_wq = create_singlethread_workqueue("hi6401_irq_delay_wq"); if (!(irq->hi6401_irq_delay_wq)) { pr_err("%s(%u) : workqueue create failed", __FUNCTION__,__LINE__); ret = -ENOMEM; goto irq_delay_wq_err; } INIT_DELAYED_WORK(&irq->hi6401_irq_delay_work, hi6401_irq_work_func); irq->pll_delay_wq = create_singlethread_workqueue("pll_delay_wq"); if (!(irq->pll_delay_wq)) { pr_err("%s : pll_delay_wq create failed", __FUNCTION__); ret = -ENOMEM; goto pll_delay_wq_err; } INIT_DELAYED_WORK(&irq->pll_delay_work, hi6401_pll_work_func); g_dump_buf = (char*)kmalloc(sizeof(char)*Hi6401_SIZE_MAX, GFP_KERNEL); if (!g_dump_buf) { pr_err("%s : couldn't malloc buffer.\n",__FUNCTION__); ret = -ENOMEM; goto g_dump_buf_kmalloc_err; } memset(g_dump_buf, 0, Hi6401_SIZE_MAX); /* populate sub nodes */ of_platform_populate(np, of_hi6401_irq_child_match_tbl, NULL, dev); if (!hi6401_client) { hi6401_client = dsm_register_client(&dsm_hi6401); } return 0; g_dump_buf_kmalloc_err: if(irq->pll_delay_wq) { cancel_delayed_work(&irq->pll_delay_work); flush_workqueue(irq->pll_delay_wq); destroy_workqueue(irq->pll_delay_wq); } pll_delay_wq_err: if(irq->hi6401_irq_delay_wq) { cancel_delayed_work(&irq->hi6401_irq_delay_work); flush_workqueue(irq->hi6401_irq_delay_wq); destroy_workqueue(irq->hi6401_irq_delay_wq); } irq_delay_wq_err: free_irq(irq->irq, irq); gpio_err: gpio_free(irq->gpio); get_gpio_err: clk_disable_unprepare(irq->pmu_audio_clk); pmu_audio_clk_enable_err: devm_clk_put(dev, irq->pmu_audio_clk); pmu_audio_clk_err: clk_disable_unprepare(irq->codec_ssi_clk); codec_ssi_clk_enable_err: devm_clk_put(dev, irq->codec_ssi_clk); codec_ssi_clk_err: codec_ssi_iomux_idle(irq->pctrl); codec_ssi_iomux_err: pinctrl_put(irq->pctrl); codec_ssi_get_err: devm_iounmap(dev, irq->reg_base_addr); ioremap_err: devm_release_mem_region(dev, irq->res->start, resource_size(irq->res)); err_exit: devm_kfree(dev, irq); return ret; }
void sd_sdio_enable(SDIO_Pad_Type_t io_pad_type) { struct pinctrl_state *s; int ret; if(!p){ p=devm_pinctrl_get(card_dev); if(IS_ERR(p)) printk("set pinmux error!\n"); } switch (io_pad_type) { case SDHC_CARD_0_5 : //SDHC-B #ifdef CONFIG_OF s = pinctrl_lookup_state(p, "sdhc_b"); if (IS_ERR(s)) { devm_pinctrl_put(p); p=NULL; } ret = pinctrl_select_state(p, s); if (ret < 0) { devm_pinctrl_put(p); p=NULL; } #else pinmux_set(&SDHC_CARD_0_5_set); #endif SET_CBUS_REG_MASK(SDIO_MULT_CONFIG, (1)); break; case SDHC_BOOT_0_11 : //SDHC-C #ifdef CONFIG_OF s = pinctrl_lookup_state(p, "sdhc_c"); if (IS_ERR(s)) { pinctrl_put(p); p=NULL; } ret = pinctrl_select_state(p, s); if (ret < 0) { pinctrl_put(p); p=NULL; } #else pinmux_set(&SDHC_BOOT_0_11_set); #endif SET_CBUS_REG_MASK(SDIO_MULT_CONFIG, (2)); break; case SDHC_GPIOX_0_9 : //SDHC-A #ifdef CONFIG_OF s = pinctrl_lookup_state(p, "sdhc_a"); if (IS_ERR(s)) { pinctrl_put(p); p=NULL; } ret = pinctrl_select_state(p, s); if (ret < 0) { pinctrl_put(p); p=NULL; } #else pinmux_set(&SDHC_GPIOX_0_9_set); #endif SET_CBUS_REG_MASK(SDIO_MULT_CONFIG, (0)); break; default : printk("invalid hw io pad!!!\n"); break; } return; }