static long tpa6132_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    int ret = 0;

    mutex_lock(&tpa6132_lock);
    switch (cmd) {
    case TPA6132_ENABLE:
        ret = blockmux_set(tpa6132_iomux_block, tpa6132_block_config, NORMAL);
        if (0 > ret) {
            loge("%s: set iomux to gpio normal error", __FUNCTION__);
            goto err_exit;
        }
        gpio_set_value(pdata->gpio_tpa6132_en, 1);
        break;
    case TPA6132_DISABLE:
        gpio_set_value(pdata->gpio_tpa6132_en, 0);
        ret = blockmux_set(tpa6132_iomux_block, tpa6132_block_config, LOWPOWER);
        if (0 > ret) {
            loge("%s: set iomux to gpio lowpower error", __FUNCTION__);
            goto err_exit;
        }
        break;
    default:
        loge("%s: invalid command %d", __FUNCTION__, _IOC_NR(cmd));
        ret = -EINVAL;
        break;
    }

err_exit:
    mutex_unlock(&tpa6132_lock);
    return ret;
}
Esempio n. 2
0
static void mshci_hi_sdio_set_power(struct platform_device *dev, int val)
{
	struct mshci_host *host = platform_get_drvdata(dev);
	struct himci_host * hi_host = (struct himci_host *)(host->private);
	/*int ret = -1;*/
	u32 loop_count = 1000; /* wait 10S */
	u32 i = 0;

	himci_assert(host);
	himci_assert(hi_host);

	for (i = 0; i < loop_count; i++) {
		if (MMC_HOST_BUSY == host->working || host->mrq) {
			msleep(10);
		} else {
			break;
		}
	}
#if 0
	if (val) {
		printk("%s:val=%d, set io to normal mode\n", __func__, val);
		host->mmc->ios.power_mode = MMC_POWER_UP;
		host->mmc->ios.timing = MMC_TIMING_LEGACY;
		host->mmc->ios.bus_width = MMC_BUS_WIDTH_1;
		host->mmc->ios.clock = 0;
		host->mmc->ops->set_ios(host->mmc, &host->mmc->ios);

		ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
		if (ret) {
			himci_error("failed to blockmux_set");
		}
		msleep(10);

		host->mmc->ios.power_mode = MMC_POWER_ON;
		host->mmc->ios.clock = 400000;
		host->mmc->ops->set_ios(host->mmc, &host->mmc->ios);

		//to do w00215368
		//blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
	} else {
		printk("%s:val=%d, set io to lowpower mode\n", __func__, val);
		host->mmc->ios.clock = 0;
		host->mmc->ios.power_mode = MMC_POWER_OFF;
		host->mmc->ios.bus_width = MMC_BUS_WIDTH_1;
		host->mmc->ios.timing = MMC_TIMING_LEGACY;

		ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
		if (ret) {
			himci_error("failed to blockmux_set");
		}
	}
#endif
}
static int st_host_wake_resume(struct platform_device *pdev)
{
	int ret;
	unsigned long irq_flags = 0;

	pr_err("%s", __func__);

	if (test_bit(ST_HOST_WAKE, &flags) && test_bit(IRQ_WAKE, &flags)) {
		ret = blockmux_set(btuart4_block, btuart4_config, NORMAL);
		if (ret) {
			pr_info("%s: btuart4_block blockmux set err %d\r\n", __func__, ret);
			return ret;
		}

#ifdef IRQ_WAKEUP
		ret = disable_irq_wake(hwi->host_wake_irq);
		if (ret < 0)	{
			pr_err("%s: couldn't disable ST_HOST_WAKE as wakeup interrupt %d", __func__, ret);
		}
#endif
		clear_bit(IRQ_WAKE, &flags);
	}

	return 0;
}
Esempio n. 4
0
static int hi_mci_resume(struct platform_device *dev)
{
	int ret = 0;
	struct mshci_host *ms_host = NULL;
	struct himci_host *hi_host = NULL;   
	int cbp_flag = 0;
	int cbp_ret = 0;
	unsigned int oldclock = 0;

	ms_host = platform_get_drvdata(dev);
	if (!ms_host) {
		printk(KERN_WARNING "the return value of platform_get_drvdata is NULL !\n");
		return -1;
	}
	hi_host = mshci_priv(ms_host);

	cbp_ret = get_hw_config_int("modem/viacbp82d", &cbp_flag, NULL);
	if ((!cbp_ret) || (0 == cbp_flag)) {
		pr_info("%s has no cbp support\n", __func__);
	}

	if ((1 == hi_host->pdev->id)&&(cbp_flag)){
		ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
		if (ret) {
			himci_error("failed to blockmux_set");
		}
	}

	printk(KERN_INFO "hi_mci_resume is called \n");
	mshci_resume_host(ms_host);

	if (ms_host->quirks & MSHCI_QUIRK_WLAN_DETECTION) {
		if (ms_host->mmc->ios.power_mode != MMC_POWER_OFF) {
			ret = mmc_sdio_resume_ext(ms_host->mmc);
			if (ret) {
				printk("%s, sdio resume error\n", __func__);
				return ret;
			}
		}
	}

	if ((1 == hi_host->pdev->id)&&(cbp_flag)){
		if (ms_host->mmc->ios.power_mode != MMC_POWER_OFF) {
			pr_info("%s cbp resume sdio maxclock = %d, cur_clk=%d\n", __func__, ms_host->max_clk, ms_host->clock);
			ms_host->mmc->ios.clock = ms_host->mmc->f_max;
			ms_host->mmc->ops->set_ios(ms_host->mmc, &ms_host->mmc->ios);
			ms_host->mmc->ops->enable_sdio_irq(ms_host->mmc, 1);
		}
		cbp_host_waked = 1;
		cbp_notifier_call_chain(1, NULL);
	}

    if(0 == hi_host->pdev->id)
    {
        g_ulmmc_suspend_flag = false;
        /*emmc resume 完毕*/
        printk("mmc_blk_resume, clr g_ulmmc_suspend_flag.\n");
    }
	return ret;
}
static void adxl34x_disable(struct adxl34x *ac)
{
	short buf[3];

	mutex_lock(&ac->mutex);
	if (!ac->disabled) {
		ac->disabled = 1;

/* must unmask interrupt before cancel work or it will cause unstable */
		AC_WRITE(ac, INT_ENABLE, 0);
		mutex_unlock(&ac->mutex);
		/* ret =cancel_work_sync(&ac->work); */
		flush_work(&ac->work);
		mutex_lock(&ac->mutex);
		/*
		 * A '0' places the ADXL34x into standby mode
		 * with minimum power consumption.
		 */
/* make sure interrupt is cleared */
		AC_READ(ac, INT_SOURCE);
		ac->read_block(ac->bus, DATAX0, DATAZ1 - DATAX0 + 1,
			   (unsigned char *)buf);
		AC_WRITE(ac, POWER_CTL, 0);

		if (blockmux_set(ac->gpio_block, ac->gpio_block_config, LOWPOWER))
			dev_err(&ac->bus->dev, "%s, blockmux_set gpio config err\n",
				__func__);

	}

	mutex_unlock(&ac->mutex);
}
static void K3_gps_bcm_shutdown(struct platform_device *pdev)
{
	GPS_BCM_INFO *gps_bcm = platform_get_drvdata(pdev);
#ifdef CONFIG_MACH_K3V2OEM1
	int ret = 0;
#endif

	if (!gps_bcm) {
		dev_err(&pdev->dev, "gps_bcm is NULL\n");
		return;
	}

	printk("[%s] +\n", __func__);

	gpio_set_value(gps_bcm->gpioid_en, 0);
	gpio_set_value(gps_bcm->gpioid_ret, 0);

#ifdef CONFIG_MACH_K3V2OEM1
	if ((gps_bcm->piomux_block) && (gps_bcm->pblock_config)) {
		ret = blockmux_set(gps_bcm->piomux_block, gps_bcm->pblock_config, LOWPOWER);
		if (ret)
			dev_err(&pdev->dev, "Set gps iomux to LOWPOWER failed, ret=%d\n", ret);
	}

	clk_disable(gps_bcm->clk);
	clk_put(gps_bcm->clk);
#else
	gpio_set_value(gps_bcm->gpioid_ret, 0);
	gpio_free(gps_bcm->gpioid_power);
#endif

	printk("[%s] -\n", __func__);
}
Esempio n. 7
0
static halReturn_t HalGpioConfigStatus(enum iomux_func status)
{
    int ret = 0;
    struct iomux_block *pMhlGpioBlock = NULL;
    struct block_config *pMhlGpioBlockConfig = NULL;

    /* get gpio block*/
    pMhlGpioBlock = iomux_get_block(MHL_GPIO_BLOCK_NAME);
    if (IS_ERR(pMhlGpioBlock))
    {
        SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE,"HalGpioSetResource: Get GPIO Block Failed\n");
        return HAL_RET_FAILURE;
    }

    /* get gpio block config*/
    pMhlGpioBlockConfig = iomux_get_blockconfig(MHL_GPIO_BLOCK_NAME);
    if (IS_ERR(pMhlGpioBlockConfig))
    {
        SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE,"HalGpioSetResource: get GPIO Block Config Failed\n");
        return HAL_RET_FAILURE;
    }

    /* config gpio work mode*/
    ret = blockmux_set(pMhlGpioBlock, pMhlGpioBlockConfig, status);
    if (ret)
    {
        SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE,"HalGpioConfigStatus: Config GPIO Block  Failed\n");
        return HAL_RET_FAILURE;
    }

    return HAL_RET_SUCCESS;
}
Esempio n. 8
0
static int __devexit k3_bq24161_charger_remove(struct i2c_client *client)
{
	struct k3_bq24161_device_info *di = i2c_get_clientdata(client);

	/**********ADD BY 00186176 begin****************/
	hiusb_charger_unregiste_notifier(&di->nb);
	/**********ADD BY 00186176 END****************/

	sysfs_remove_group(&client->dev.kobj, &k3_bq24161_attr_group);

	cancel_delayed_work(&di->bq24161_charger_work);
	flush_scheduled_work();

#if BQ2416X_USE_WAKE_LOCK
	wake_lock_destroy(&di->charger_wake_lock);
#endif

	gpio_free(di->gpio);

#ifdef CONFIG_GPIO_BAT
	if (blockmux_set(di->piomux_block, di->pblock_config, LOWPOWER))
		dev_err(&client->dev, "blockmux_set LOWPOWER failed\n");
	/*blockmux_set(di->piomux_block_interrupt, di->pblock_config_interrupt, LOWPOWER);*/
#endif

	kfree(di);

	return 0;
}
int st_host_wake_suspend(void)
{
	int ret;
	unsigned long irq_flags = 0;

	pr_info("%s", __func__);

	if (test_bit(ST_HOST_WAKE, &flags) && (!test_bit(IRQ_WAKE, &flags))) {

		//enable_irq(hwi->host_wake_irq);
		ret = blockmux_set(btuart4_block, btuart4_config, LOWPOWER);
		if (ret) {
			pr_info("%s	: btuart4_block blockmux set err %d\r\n", __func__, ret);
			return ret;
		}

		spin_lock_irqsave(&irq_enable_lock, irq_flags);
		suspend_flag = true;
		spin_unlock_irqrestore(&irq_enable_lock, irq_flags);

#ifdef IRQ_WAKEUP
		ret = enable_irq_wake(hwi->host_wake_irq);
		if (ret < 0)	{
			pr_err("%s: couldn't enable	ST_HOST_WAKE as	wakeup interrupt %d", __func__, ret);
		}

#endif
		set_bit(IRQ_WAKE, &flags);
		pr_info("enabled the host_wake irq");
	}

	return 0;

}
void hiusb_otg_and_phy_cleanup(void)
{
    int i;
    SOC_PERI_SCTRL_SC_PERIPH_CTRL4_UNION ao_sctrl_ctrl8;

    /* clk_disable(); */
    clk_disable(g_hiusb_info->clk_usbotg_off);
#if defined(CHIP_BB_HI6210)/*B020 Modify*/
#else
    clk_disable(g_hiusb_info->clk_picophy);
#endif
    /* ctrl 8 */
    ao_sctrl_ctrl8.value = readl(SOC_PERI_SCTRL_SC_PERIPH_CTRL4_ADDR(IO_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR)));
    ao_sctrl_ctrl8.reg.pico_siddq = 1;
    writel(ao_sctrl_ctrl8.value , SOC_PERI_SCTRL_SC_PERIPH_CTRL4_ADDR(IO_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR)));

    /* rst */
    for (i=0;hiusb_rst[i].addr != 0; i++) {
        writel(hiusb_rst[i].value, hiusb_rst[i].addr);
        udelay(hiusb_rst[i].udelay);
        pr_debug("%s rst addr:0x%8.8x value:0x%8.8x udelay:%d\n",
                __func__,
                hiusb_rst[i].addr,
                hiusb_rst[i].value,
                hiusb_rst[i].udelay);
    }

    blockmux_set(g_hiusb_info->usb_block, g_hiusb_info->usb_config, NORMAL);

    pr_info("%s -.\n", __func__);
    return;
}
void hiusb_otg_and_phy_setup(int mode)
{
    int i;
    SOC_PERI_SCTRL_SC_PERIPH_CTRL4_UNION ao_sctrl_ctrl8;
    SOC_PERI_SCTRL_SC_PERIPH_CTRL5_UNION ao_sctrl_ctrl9;

    blockmux_set(g_hiusb_info->usb_block, g_hiusb_info->usb_config, NORMAL);
    
    /* nrst */
    for (i=0;hiusb_nrst[i].addr != 0; i++) {
        writel(hiusb_nrst[i].value, hiusb_nrst[i].addr);
        udelay(hiusb_nrst[i].udelay);
        pr_debug("%s nrst addr:0x%8.8x value:0x%8.8x udelay:%d\n",
                __func__,
                hiusb_nrst[i].addr,
                hiusb_nrst[i].value,
                hiusb_nrst[i].udelay);
    }    
    
    /* ctrl 9 */
    ao_sctrl_ctrl9.value = readl(SOC_PERI_SCTRL_SC_PERIPH_CTRL5_ADDR(IO_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR)));
    ao_sctrl_ctrl9.reg.picophy_bc_mode = 0;
    if ((g_hiusb_info->quirks & HIUSB_QUIRKS_PMUIRQ) == 0) {
        if (mode == 1) {
            ao_sctrl_ctrl9.reg.picophy_iddig = 1;
        } else {
            ao_sctrl_ctrl9.reg.picophy_iddig = 0;
        }
    } else {
            ao_sctrl_ctrl9.reg.picophy_iddig = 1;
    }
#if defined(CHIP_BB_HI6210)
	ao_sctrl_ctrl9.reg.usbotg_res_sel = 1;
#endif
    writel(ao_sctrl_ctrl9.value , SOC_PERI_SCTRL_SC_PERIPH_CTRL5_ADDR(IO_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR)));

    /* ctrl 8 */
    ao_sctrl_ctrl8.value = readl(SOC_PERI_SCTRL_SC_PERIPH_CTRL4_ADDR(IO_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR)));
    ao_sctrl_ctrl8.reg.pico_siddq = 0;
    ao_sctrl_ctrl8.reg.pico_ogdisable = 0;
    ao_sctrl_ctrl8.reg.pico_vbusvldextsel = 1;
    ao_sctrl_ctrl8.reg.pico_vbusvldext = 1;
    writel(ao_sctrl_ctrl8.value , SOC_PERI_SCTRL_SC_PERIPH_CTRL4_ADDR(IO_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR)));
    udelay(60);

    writel(0x703334d8, SOC_PERI_SCTRL_SC_PERIPH_CTRL8_ADDR(IO_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR)));

    // clk_enable();
    clk_enable(g_hiusb_info->clk_usbotg_off);
#if defined(CHIP_BB_HI6210)/*B020 Modify*/
#else
    clk_enable(g_hiusb_info->clk_picophy);
#endif


    pr_info("%s .\n", __func__);

    return;
}
void LCD_IOMUX_SET(struct k3_panel_info *pinfo, int mode)
{
	BUG_ON(pinfo == NULL);

	if (blockmux_set(pinfo->lcd_block, pinfo->lcd_block_config, mode) != 0) {
		k3fb_loge("failed to set iomux_lcd normal mode!\n");
	}
}
void PWM_IOMUX_SET(struct k3_panel_info *pinfo, int mode)
{
	BUG_ON(pinfo == NULL);

	if (blockmux_set(pinfo->pwm_block, pinfo->pwm_block_config, (mode)) != 0) {
		k3fb_loge("failed to set iomux pwm normal mode!\n");
	}
}
static int gpio_lowpower_set(enum iomux_func newmode)
{
	int ret;
	ret = blockmux_set(xmm_iomux_block, xmm_iomux_config, newmode);
	if (ret) {
		pr_info("SETERROR:blockmux set err\r\n");
		return -1;
	}
	return 0;
}
static int set_iomux_lowpower(struct iomux_block *gpio_block,struct block_config *gpio_block_config)
{
    int ret;
    
    BUG_ON(gpio_block_config==NULL);
    BUG_ON(gpio_block==NULL);
    
    ret = blockmux_set(gpio_block, gpio_block_config, LOWPOWER);
    if (ret<0) {
        printk(KERN_ERR "%s: failed to config gpio\n", __func__);
        return ret;
    }

    return 0;
}
Esempio n. 16
0
int iomux_cmds_tx(struct iomux_desc *cmds, int cnt)
{
	struct iomux_desc *cm = NULL;
	int i = 0;

	cm = cmds;

	for (i = 0; i < cnt; i++) {
		if (cm == NULL) {
			k3fb_loge("cm(%d) is null!\n", i);
			continue;
		}

		BUG_ON(cm->name == NULL);

		if (cm->dtype == DTYPE_IOMUX_GET) {
			if (cm->name == NULL) {
				k3fb_loge("Block name is NULL!\n");
			}
			*(cm->block) = iomux_get_block(cm->name);
			if (*(cm->block) == NULL) {
				k3fb_loge("failed to iomux_get_block, name=%s!\n",
					(cm->name == NULL) ? "NULL" : cm->name);

				continue;
			}

			*(cm->block_config) = iomux_get_blockconfig(cm->name);
			if (*(cm->block_config) == NULL) {
				k3fb_loge("failed to iomux_get_blockconfig, name=%s!\n",
					(cm->name == NULL) ? "NULL" : cm->name);

				continue;
			}
		} else if (cm->dtype == DTYPE_IOMUX_SET) {
			if (blockmux_set(*(cm->block), *(cm->block_config), cm->mode) != 0) {
				k3fb_loge("failed to blockmux_set, name=%s!\n",
					(cm->name == NULL) ? "NULL" : cm->name);

				continue;
			}
		}

		cm++;
	}

	return cnt;
}
Esempio n. 17
0
static int __init k3v2_wifi_init(void)
{
	int ret = 0;

	printk("TI WL18XX: %s \n", __func__);

        wifi_host = kzalloc(sizeof(struct wifi_host_s), GFP_KERNEL);
        wifi_host->clk = clk_get(NULL, "clk_pmu32kb");
        //delete the regulator LDO14 that wifi not used
        wifi_host->block = iomux_get_block("block_wifi");
        wifi_host->config = iomux_get_blockconfig("block_wifi");
        blockmux_set(wifi_host->block, wifi_host->config, LOWPOWER);

	/* set power gpio */
	ret = gpio_request(K3V2_WIFI_POWER_GPIO, NULL);
	if (ret < 0) {
		pr_err("%s: gpio_request failed, ret:%d.\n", __func__,
			K3V2_WIFI_POWER_GPIO);
		goto err_power_gpio_request;
	}
	gpio_direction_output(K3V2_WIFI_POWER_GPIO, 0);

	//z00186406 add to request out band irq, and convert gpio number to irq number begin
	ret = gpio_request(K3V2_WIFI_IRQ_GPIO, NULL);
	if(ret < 0) {
		pr_err( "%s: gpio_request failed, ret:%d.\n", __func__,
			K3V2_WIFI_IRQ_GPIO );
		goto err_irq_gpio_request;
	}
	gpio_direction_input(K3V2_WIFI_IRQ_GPIO);
	k3v2_wlan_data.irq = gpio_to_irq(K3V2_WIFI_IRQ_GPIO);
	//z00186406 add to request out band irq, and convert gpio number to irq number end

	wl12xx_set_platform_data(&k3v2_wlan_data);

	return 0;

//z00186406 add enable out band irq begin
err_irq_gpio_request:
       gpio_free(K3V2_WIFI_IRQ_GPIO);
//z00186406 add enable out band irq end

err_power_gpio_request:
	gpio_free(K3V2_WIFI_POWER_GPIO);
	return ret;
}
Esempio n. 18
0
void __init iomux_init_blocks(void)
{
	int ret;
	struct  iomux_block *block_temp = NULL;
	struct block_config *config_temp = NULL;
	struct  block_table *table_temp = NULL;

	get_active_block_table();
	table_temp = p_active_block_table;
	while ((*table_temp).name) {
		block_temp = (*table_temp).block;
		config_temp = (*table_temp).config_array;
		ret = blockmux_set(block_temp, config_temp, LOWPOWER);
		if (ret) {
			pr_err("IOMUX:iomux initialized failed.\r\n");
			break;
		}
		table_temp++;
	}
}
Esempio n. 19
0
static int adxl34x_config_gpio(struct device *dev, struct adxl34x *acc_data)
{

	int ret = 0;

	/* get gpio block*/
	acc_data->gpio_block = iomux_get_block(GPIO_BOLCK_NAME);
	if (IS_ERR(acc_data->gpio_block)) {
		dev_err(dev, "%s: failed to get gpio block\n", __func__);
		ret = -EINVAL;
		return ret;
	}

	/* get gpio block config*/
	acc_data->gpio_block_config = iomux_get_blockconfig(GPIO_BOLCK_NAME);
	if (IS_ERR(acc_data->gpio_block_config)) {
		dev_err(dev, "%s: failed to get gpio block config\n", __func__);
		ret = -EINVAL;
		goto err_block_config;
	}

	/* config gpio work mode*/
	ret = blockmux_set(acc_data->gpio_block, acc_data->gpio_block_config, LOWPOWER);
	if (ret) {
		dev_err(dev, "%s: failed to config gpio\n", __func__);
		ret = -EINVAL;
		goto err_mux_set;
	}

	return ret;

err_mux_set:
	if (acc_data->gpio_block_config)
		acc_data->gpio_block_config = NULL;
err_block_config:
	if (acc_data->gpio_block)
		acc_data->gpio_block = NULL;

	return ret;

}
Esempio n. 20
0
/**********ADD BY 00186176 begin****************/
static void k3_bq24161_charger_shutdown(struct i2c_client *client)
{
	struct k3_bq24161_device_info *di = i2c_get_clientdata(client);

	printk("[%s] +\n", __func__);

	cancel_delayed_work(&di->bq24161_charger_work);
	flush_scheduled_work();


	/**********ADD BY 00186176 begin****************/
#ifdef CONFIG_GPIO_BAT
	if (blockmux_set(di->piomux_block, di->pblock_config, LOWPOWER))
		dev_err(&client->dev, "blockmux_set LOWPOWER failed\n");
#endif
	/**********ADD BY 00186176 END****************/

	printk("[%s] -\n", __func__);

	return;
}
Esempio n. 21
0
static int adxl34x_enable(struct adxl34x *ac)
{
	int err = 0;

	mutex_lock(&ac->mutex);
	if (ac->disabled) {
		err = blockmux_set(ac->gpio_block, ac->gpio_block_config, NORMAL);
		if (err) {
			dev_err(&ac->bus->dev, "%s, blockmux_set gpio config err %d\n",
				__func__, err);
			mutex_unlock(&ac->mutex);
			return err;
		}
		AC_WRITE(ac, POWER_CTL, PCTL_MEASURE);
		AC_WRITE(ac, INT_ENABLE, ac->int_mask /*| OVERRUN*/);
		ac->disabled = 0;
	}
	mutex_unlock(&ac->mutex);

	return err;

}
static int __devexit k3_gps_bcm_remove(struct platform_device *pdev)
{
	GPS_BCM_INFO *gps_bcm = platform_get_drvdata(pdev);
	int ret = 0;

	dev_dbg(&pdev->dev, "k3_gps_bcm_remove +\n");

	if (!gps_bcm) {
		dev_err(&pdev->dev, "gps_bcm is NULL\n");
		return 0;
	}

#ifdef CONFIG_MACH_K3V2OEM1
	if ((gps_bcm->piomux_block) && (gps_bcm->pblock_config)) {
		ret = blockmux_set(gps_bcm->piomux_block, gps_bcm->pblock_config, LOWPOWER);
		if (ret)
			dev_err(&pdev->dev, "Set gps iomux to LOWPOWER failed, ret=%d\n", ret);
	}

	clk_disable(gps_bcm->clk);
	clk_put(gps_bcm->clk);
#else
	gpio_free(gps_bcm->gpioid_power);
#endif

	gpio_free(gps_bcm->gpioid_en);
	gpio_free(gps_bcm->gpioid_ret);

	kfree(gps_bcm);
	gps_bcm = NULL;
	platform_set_drvdata(pdev, NULL);

	dev_dbg(&pdev->dev, "k3_gps_bcm_remove -\n");

	return ret;
}
Esempio n. 23
0
/*NOT called by VIA*/
static void mshci_sd_power_onoff(struct mshci_host *ms_host,int ispowerup)
{
    struct himci_host * hi_host = (struct himci_host *)(ms_host->private);
    int ret = 0;

    if (sd_ldo22_need_control){/* during power-on or power-off,need to restore sd io if necessary  */       
		pmussi_reg_write(SOC_SMART_ENABLE4_ADDR(0),BIT(SOC_SMART_ENABLE4_en_ldo22_int_START));
		udelay(30);
		pmussi_reg_write(SOC_SMART_LDO7_REG_ADJ_ADDR(0),SDMMC_3V3_IO_LDO7_SSI_VALUE);
		sd_ldo22_need_control = 0;
    }
    if (ispowerup){

        udelay(30);
        if (hi_host->signal_vcc){
            ret = regulator_enable(hi_host->signal_vcc);
            if (ret) {
               himci_error("failed to regulator_enable");
            }
        }
        udelay(30);
        if (hi_host->vcc_lvs){
            ret = regulator_enable(hi_host->vcc_lvs);
            if (ret) {
               himci_error("failed to regulator_enable");
            }
        }

        if (hi_host->vcc_ldo) {
            ret = regulator_set_voltage(hi_host->vcc_ldo, SDMMC_SDCARD_285, SDMMC_SDCARD_285);
            if (ret != 0) {
                himci_error("failed to LDO10 regulator_set_voltage 2.85 \n");
            }
        }
        if (hi_host->vcc_ldo){
            ret = regulator_enable(hi_host->vcc_ldo);
            if (ret) {
                himci_error("failed to regulator_enable");
            }
        }
        ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
		if (ret) {
		    himci_error("failed to blockmux_set");
		}
    }
    else{
        ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
		if (ret) {
		    himci_error("failed to blockmux_set");
		}
        mshci_sd_lowpower();
		if (hi_host->vcc_ldo){
            ret = regulator_disable(hi_host->vcc_ldo);
            if (ret) {
                himci_error("failed to regulator_disable LDO10");
            }
        }
        if (hi_host->vcc_lvs){
            ret = regulator_disable(hi_host->vcc_lvs);
            if (ret) {
               himci_error("failed to regulator_disable LDO7");
            }
        }
        udelay(30);
        if (hi_host->signal_vcc){
            ret = regulator_disable(hi_host->signal_vcc);
            if (ret) {
               himci_error("failed to regulator_disable LDO22");
            }
        }
    }
}
Esempio n. 24
0
static int __devinit k3_bq24161_charger_probe(struct i2c_client *client,
				 const struct i2c_device_id *id)
{
	u8 read_reg = 0;
	int ret = 0;
	enum usb_charger_type plugin_stat = CHARGER_REMOVED;
	struct k3_bq24161_device_info *di = NULL;
	struct k3_bq24161_platform_data *pdata = NULL;
	/*enum plugin_status plugin_stat;*/

	if (!g_battery_measure_by_bq27510_device) {
		dev_err(&client->dev, "g_battery_measure_by_bq27510_device is NULL!\n");
		return -ENOMEM;
	}

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_err(&client->dev, "pdata is NULL!\n");
		return -ENOMEM;
	}

	di = kzalloc(sizeof(*di), GFP_KERNEL);
	if (!di) {
		dev_err(&client->dev, "di is NULL!\n");
		return -ENOMEM;
	}

	di->dev = &client->dev;
	di->client = client;

	i2c_set_clientdata(client, di);

	ret = k3_bq24161_read_byte(di, &read_reg, REG_PART_REVISION);

	if (ret < 0) {
		dev_err(&client->dev, "chip not present at address %x\n",
								client->addr);
		ret = -EINVAL;
		goto err_kfree;
	}

	if (((read_reg & BQ24161_VERSION_MSK) == 0x00)
		&& (client->addr == I2C_ADDR_BQ24161))
		di->bqchip_version = BQ24161;

	if (di->bqchip_version == 0) {
		dev_err(&client->dev, "unknown bq chip\n");
		dev_err(&client->dev, "Chip address %x", client->addr);
		dev_err(&client->dev, "bq chip version reg value %x", read_reg);
		ret = -EINVAL;
		goto err_kfree;
	}

	di->max_voltagemV = pdata->max_charger_voltagemV;
	di->max_currentmA = pdata->max_charger_currentmA;
	di->voltagemV = di->max_voltagemV;
	di->currentmA = CURRENT_USB_CHARGE_IN ;
	di->term_currentmA = CURRENT_TERM_CHARGE_IN;
	di->dppm_voltagemV = VOLT_DPPM_ADJUST;
	di->cin_limit = CURRENT_USB_LIMIT_IN;
	di->gpio = pdata->gpio;

	/**********ADD BY 00186176 begin****************/
	 /* Set iomux normal */
#ifdef CONFIG_GPIO_BAT
	if (!di->piomux_block)
		di->piomux_block  = iomux_get_block("block_charger");

	if (!di->pblock_config)
		di->pblock_config = iomux_get_blockconfig("block_charger");

	ret = blockmux_set(di->piomux_block, di->pblock_config, NORMAL);
	if (ret) {
		dev_err(&client->dev, "blockmux_set NORMAL failed, ret=%d\n", ret);
		goto err_kfree;
	}
#endif

    /*set gpio_074 to control CD pin to disable/enable bq24161 IC*/
	ret = gpio_request(di->gpio, "gpio_074_cd");
	if (ret) {
		dev_err(&client->dev, "could not request irq\n");
		ret = -ENOMEM;
		goto err_io;
	}

	 /* set charger CD pin to low level and enable it to supply power normally*/
	gpio_direction_output(di->gpio, 0);

	 /**********ADD BY 00186176 END****************/

	di->enable_low_chg = ENABLE_LOW_CHG;

	/*enable low charge,100mA charging*/
	k3_bq24161_config_safety_reg(di);

	/*disable charge current termination*/
	di->enable_iterm = DISABLE_ITERM;

	di->factory_flag = 0;

	di->enable_ce = ENABLE_CE;
	di->hz_mode = 0;
	di->cd_active = 0;

#if BQ2416X_USE_WAKE_LOCK
	wake_lock_init(&di->charger_wake_lock, WAKE_LOCK_SUSPEND, "charger_wake_lock");
#endif

	INIT_DELAYED_WORK(&di->bq24161_charger_work,
				k3_bq24161_charger_work);

	INIT_WORK(&di->usb_work, k3_bq24161_usb_charger_work);

	di->active = 0;
	di->params.enable = 1;
	di->cfg_params = 1;
	/*di->enable_iterm = 1;*/

	k3_bq24161_config_control_reg(di);
	k3_bq24161_config_voltage_reg(di);
	k3_bq24161_config_current_reg(di);
	k3_bq24161_config_dppm_voltage_reg(di, di->dppm_voltagemV);
	k3_bq24161_config_safety_reg(di);

	ret = sysfs_create_group(&client->dev.kobj, &k3_bq24161_attr_group);
	if (ret) {
		dev_err(&client->dev, "could not create sysfs files\n");
		goto err_gpio;
	}

	/**********ADD BY 00186176 begin****************/

	di->nb.notifier_call = k3_bq24161_usb_notifier_call;

	ret = hiusb_charger_registe_notifier(&di->nb);
	if (ret < 0) {
		dev_err(&client->dev, "hiusb_charger_registe_notifier failed\n");
		goto err_sysfs;
	}

	plugin_stat = get_charger_name();
	if ((CHARGER_TYPE_USB == plugin_stat) || (CHARGER_TYPE_NON_STANDARD == plugin_stat)) {
		di->event = plugin_stat;
		k3_bq24161_start_500mA_charger(di);
	} else if (CHARGER_TYPE_BC_USB == plugin_stat) {
		k3_bq24161_start_BCUSB_charger(di);
	} else if (CHARGER_TYPE_STANDARD == plugin_stat) {
		k3_bq24161_start_ac_charger(di);
	} else {
		k3_bq24161_stop_charger(di);
	}

	return 0;

err_sysfs:
	sysfs_remove_group(&client->dev.kobj, &k3_bq24161_attr_group);
err_gpio:
	gpio_free(di->gpio);
err_io:
#ifdef CONFIG_GPIO_BAT
	if (blockmux_set(di->piomux_block, di->pblock_config, LOWPOWER))
		dev_err(&client->dev, "blockmux_set LOWPOWER failed\n");
#endif
	/**********ADD BY 00186176 END****************/
err_kfree:
	kfree(di);
	di = NULL;

	return ret;
}
/*
 **************************************************************************
 * FunctionName: ispv1_ioconfig;
 * Description : iomux config;
 * Input       : power_state: on/off
 * Output      : NA;
 * ReturnValue : NA;
 * Other       : NA;
 **************************************************************************
 */
static int ispv1_ioconfig(camera_power_state power_state, data_interface_t type)
{

	int ret = 0;
	print_info("%s camera iomux config", __func__);

    /* Modified  by w00199382 for isp 2.2 , 2012/11/23, begin */
#if 0
	if (power_state == POWER_ON) {
		ret = blockmux_set(ispv1_io.block_i2c, ispv1_io.block_conf_i2c, NORMAL);
		if (ret != 0) {
			print_error("%s: failed to set iomux dvp to normal mode.\n", __func__);
		}

		ret |= blockmux_set(ispv1_io.block_rst, ispv1_io.block_conf_rst, NORMAL);
		if (ret != 0) {
			print_error("%s: failed to set iomux dvp to normal mode.\n", __func__);
		}

		ret |= blockmux_set(ispv1_io.block_isp, ispv1_io.block_conf_isp, NORMAL);
		if (ret != 0) {
			print_error("%s: failed to set iomux isp to GPIO mode.\n", __func__);
		}

		if (type == DVP) {
			ret |= blockmux_set(ispv1_io.block_dvp, ispv1_io.block_conf_dvp, NORMAL);
			if (ret != 0) {
				print_error("%s: failed to set iomux dvp to normal mode.\n", __func__);
			}
		}
	} else {
		ret = blockmux_set(ispv1_io.block_i2c, ispv1_io.block_conf_i2c, LOWPOWER);
		if (ret != 0) {
			print_error("%s: failed to set iomux dvp to normal mode.\n", __func__);
		}

		ret |= blockmux_set(ispv1_io.block_rst, ispv1_io.block_conf_rst, LOWPOWER);
		if (ret != 0) {
			print_error("%s: failed to set iomux dvp to normal mode.\n", __func__);
		}
		ret |= blockmux_set(ispv1_io.block_isp, ispv1_io.block_conf_isp, LOWPOWER);
		if (ret != 0) {
			print_error("%s: failed to set iomux isp to GPIO mode.\n", __func__);
		}

		if (type == DVP) {
			ret |= blockmux_set(ispv1_io.block_dvp, ispv1_io.block_conf_dvp, LOWPOWER);
			if (ret != 0) {
				print_error("%s: failed to set iomux dvp to normal mode.\n", __func__);

			}

		}

	}
#endif
    /* Modified  by w00199382 for isp 2.2 , 2012/11/23, end */

#if defined(CONFIG_ARCH_HI6620)
	if (power_state == POWER_ON) {
		ret = pinctrl_select_state(ispv1_io.isp_pinctrl, ispv1_io.pinctrl_def); //work mode
		if (ret != 0) {
			print_error("%s: failed to set iomux scam/mcam to normal mode.\n", __func__);
		}
	} else {
		ret =pinctrl_select_state(ispv1_io.isp_pinctrl, ispv1_io.pinctrl_idle); 
		if (ret != 0) {
			print_error("%s: failed to set iomux scam/mcam to lowpower mode.\n", __func__);
		}
		}
#endif

	return ret;

}
static int __devinit k3_gps_bcm_probe(struct platform_device *pdev)
{
	GPS_BCM_INFO *gps_bcm;
	struct resource *res;
	int ret = 0;

	gps_bcm = kzalloc(sizeof(GPS_BCM_INFO), GFP_KERNEL);
	if (!gps_bcm) {
		dev_err(&pdev->dev, "Alloc memory failed\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, gps_bcm);

	/* Get enable gpio */
	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (!res) {
		dev_err(&pdev->dev, "Get enable gpio resourse failed\n");
		ret = -ENXIO;
		goto err_free;
	}
	gps_bcm->gpioid_en = res->start;

	ret = gpio_request(gps_bcm->gpioid_en, "gps_enbale");
	if (ret < 0) {
		dev_err(&pdev->dev,  "gpio_request failed, gpio=%lu, ret=%d\n", gps_bcm->gpioid_en, ret);
		goto err_free;
	}
	gpio_export(gps_bcm->gpioid_en, false);

	/* Get reset gpio */
	res = platform_get_resource(pdev, IORESOURCE_IO, 1);
	if (!res) {
		dev_err(&pdev->dev, "Get reset gpio resourse failed\n");
		ret = -ENXIO;
		goto err_free_gpio_en;
	}
	gps_bcm->gpioid_ret = res->start;

	ret = gpio_request(gps_bcm->gpioid_ret, "gps_reset");
	if (ret < 0) {
		dev_err(&pdev->dev,  "gpio_request failed, gpio=%lu, ret=%d\n", gps_bcm->gpioid_ret, ret);
		goto err_free_gpio_en;
	}
	gpio_export(gps_bcm->gpioid_ret, false);

#ifndef CONFIG_MACH_K3V2OEM1
	/* Get power gpio (VDDIO 1.8V), Only for FPGA */
	res = platform_get_resource(pdev, IORESOURCE_IO, 2);
	if (!res) {
		dev_err(&pdev->dev, "Get power gpio resourse failed\n");
		ret = -ENXIO;
		goto err_free_gpio_ret;
	}
	gps_bcm->gpioid_power = res->start;

	ret = gpio_request(gps_bcm->gpioid_power, "gps_power");
	if (ret < 0) {
		dev_err(&pdev->dev, "gpio_request failed, gpio=%lu, rc=%d\n", gps_bcm->gpioid_power, ret);
		gpio_free(gps_bcm->gpioid_en);
		goto err_free_gpio_ret;
	}

	/* Low GPS power, only for FPGA */
	gpio_direction_output(gps_bcm->gpioid_power, 0);

	/* High GPS power, only for FPGA */
	gpio_set_value(gps_bcm->gpioid_power, 1);
	dev_dbg(&pdev->dev,  "High power\n");
#else
	/* Set 32KC clock */
	gps_bcm->clk = clk_get(NULL, "clk_pmu32kc");
	if (IS_ERR(gps_bcm->clk)) {
		dev_err(&pdev->dev, "Get gps clk failed\n");
		ret = PTR_ERR(gps_bcm->clk);
		goto err_free_gpio_ret;
	}
	ret = clk_enable(gps_bcm->clk);
	if (ret) {
		dev_err(&pdev->dev, "Enable clk failed, ret=%d\n", ret);
		goto err_free_clk;
	}

	/* Set iomux NORMAL, If set iomux failed, we still go on */
	gps_bcm->piomux_block  = iomux_get_block("block_gps_boardcom");
	if (!gps_bcm->piomux_block)
		dev_err(&pdev->dev, "Get gps iomux_block failed\n");

	gps_bcm->pblock_config = iomux_get_blockconfig("block_gps_boardcom");
	if (!gps_bcm->pblock_config)
		dev_err(&pdev->dev, "Get gps block_config failed\n");

	if ((gps_bcm->piomux_block) && (gps_bcm->pblock_config)) {
		ret = blockmux_set(gps_bcm->piomux_block, gps_bcm->pblock_config, NORMAL);
		if (ret)
			dev_err(&pdev->dev, "Set gps iomux to NORMAL failed, ret=%d\n", ret);
	}
#endif

	/* Low Reset GPIO */
	gpio_direction_output(gps_bcm->gpioid_ret, 0);
	dev_dbg(&pdev->dev,  "Low reset\n");

	/* Low Enable GPIO */
	gpio_direction_output(gps_bcm->gpioid_en, 0);
	dev_dbg(&pdev->dev,  "Low enable\n");

	/* High Reset GPIO*/
	gpio_set_value(gps_bcm->gpioid_ret, 1);
	dev_dbg(&pdev->dev,  "High reset\n");

	return 0;

#ifdef CONFIG_MACH_K3V2OEM1
err_free_clk:
	clk_put(gps_bcm->clk);
#endif

err_free_gpio_ret:
	gpio_free(gps_bcm->gpioid_ret);

err_free_gpio_en:
	gpio_free(gps_bcm->gpioid_en);

err_free:
	kfree(gps_bcm);
	gps_bcm = NULL;
	return ret;
}
Esempio n. 27
0
void mshci_hi_set_ios(struct mshci_host *ms_host, struct mmc_ios *ios)
{
	struct himci_host * hi_host = (struct himci_host *)(ms_host->private);
	int ret = -1;

	hi_host_trace(HIMCI_TRACE_GEN_API, "++");

	himci_assert(ios);
	himci_assert(hi_host);

	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->power_mode = %d ", ios->power_mode);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->clock = %d ", ios->clock);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->bus_width = %d ", ios->bus_width);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->timing = %d ", ios->timing);

	/* process power */
	if (hi_host->old_power_mode != ios->power_mode) {
		switch (ios->power_mode) {
		case MMC_POWER_OFF:
		    hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to lowpower");
		    if (hi_host->vcc) {
				regulator_disable(hi_host->vcc);
		    }
			if (hi_host->signal_vcc) {
				regulator_disable(hi_host->signal_vcc);
				regulator_set_mode(hi_host->signal_vcc, REGULATOR_MODE_IDLE);
		    }

		    ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
		    if (ret) {
				himci_error("failed to blockmux_set");
		    }

			break;
		case MMC_POWER_UP:
		    hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to normal");

		    ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
		    if (ret) {
				himci_error("failed to blockmux_set");
		    }

		    if (hi_host->vcc) {
				ret = regulator_set_voltage(hi_host->vcc, 2850000, 2850000);
				if (ret != 0) {
					himci_error("failed to regulator_set_voltage");
				}

				ret = regulator_enable(hi_host->vcc);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
		    }
			if (hi_host->signal_vcc) {
				ret = regulator_set_voltage(hi_host->signal_vcc, 2600000, 2600000);
				if (ret != 0) {
					himci_error("failed to regulator_set_voltage");
				}
				regulator_set_mode(hi_host->signal_vcc, REGULATOR_MODE_NORMAL);
				ret = regulator_enable(hi_host->signal_vcc);
				if (ret) {
					himci_error("failed to regulator_enable");
				}

		    }
			break;
		case MMC_POWER_ON:
			break;
		default:
			himci_error("unknown power supply mode");
			break;
		}
		hi_host->old_power_mode = ios->power_mode;
	}

	/* process timing */
	if (hi_host->old_timing != ios->timing) {

		hi_host->old_timing = ios->timing;

		if ( get_chipid() == DI_CHIP_ID ) {
			mshci_hi_update_timing(ms_host, 0);

			switch (ios->timing) {
			case MMC_TIMING_LEGACY:
				if (hi_host->pdev->id == 1) {
					/* 2 division, 40M */
					writel((0x1<<6) | (0x7<<22),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 40*1000*1000;
					ms_host->clock++;
				} else if (hi_host->pdev->id == 0) {
					/* 2 division, 40M */
					writel((0x0<<5) | (0x1<<21),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 40*1000*1000;
					ms_host->clock++;
				}
				hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "MMC_TIMING_LEGACY");
				break;
			case MMC_TIMING_UHS_DDR50:
				if (hi_host->pdev->id == 1) {
					/* 1 division, 80M */
					writel((0x0<<6) | (0x7<<22),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 80*1000*1000;
					ms_host->clock++;
				} else {
#if 0
					/*
					 * m53980:
					 * debug purpose.
					 * change clock via sctrl configuration
					 */
					printk("clk div a:0x%x\n", readl(IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2));
					writel((0x7)|(0xF<<16), IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					printk("clk div b:0x%x\n", readl(IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2));
#endif
				}
				hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "MMC_TIMING_UHS_DDR50");
				break;
			case MMC_TIMING_UHS_SDR50:
				if (hi_host->pdev->id == 0) {
					writel((0x1<<5) | (0x1<<21),
						IO_ADDRESS(REG_BASE_SCTRL) + REG_SCCLKDIV2);
					ms_host->max_clk = 80*1000*1000;
					ms_host->clock++;
				}
				hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "MMC_TIMING_UHS_SDR50");
				break;
			default:
				break;
			}
		} else {
			ret = clk_set_rate(hi_host->pclk,hi_host->init_tuning_config[0 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM]);
			if (ret) {
				himci_error("failed to clk_set_rate");
			}
			hi_host->tuning_init_sample =
					(hi_host->init_tuning_config[3 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM] +
					hi_host->init_tuning_config[4 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM]) / 2;
			mshci_hi_set_timing(hi_host,
				hi_host->tuning_init_sample,
				hi_host->init_tuning_config[2 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM],
				hi_host->init_tuning_config[1 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM]);

			ms_host->max_clk = hi_host->init_tuning_config[5 + (ios->timing + 1) * TUNING_INIT_CONFIG_NUM];

			ms_host->clock++;
		}
	}

	hi_host_trace(HIMCI_TRACE_GEN_API, "--");
}
Esempio n. 28
0
static int hi_mci_suspend(struct platform_device *dev, pm_message_t pm)
{

	struct mshci_host *ms_host = NULL;
	struct himci_host *hi_host = NULL;
	int ret = 0;
	unsigned long flags;
	int cbp_flag = 0;
	int cbp_ret = 0;

	ms_host = platform_get_drvdata(dev);
	if (!ms_host) {
		printk(KERN_ERR "get drvdata failed !\n");
		return -1;
	}
	hi_host = mshci_priv(ms_host);

    if(0 == hi_host->pdev->id)
    {
        g_ulmmc_suspend_flag = true;
        printk("hi_mci_suspend,set g_ulmmc_suspend_flag.");
    }

	cbp_ret = get_hw_config_int("modem/viacbp82d", &cbp_flag, NULL);
	if ((!cbp_ret) || (0 == cbp_flag)) {
		pr_info("%s has no cbp support\n", __func__);
	}

	if ((1 == hi_host->pdev->id)&&(cbp_flag)){
		if (ms_host->mmc->ios.power_mode != MMC_POWER_OFF) {
			pr_info("%s cbp ext suspend sdio\n", __func__);
			if (cbp_in_sdio_tras){
				pr_info("%s cbp_in_sdio_tras %d\n", __func__, cbp_in_sdio_tras);
				return -EAGAIN;
			}
			cbp_clock_enabled = 0;
			cbp_host_waked = 0;
			cbp_notifier_call_chain(0, NULL);

			ms_host->mmc->ios.power_mode = MMC_POWER_UP;
			ms_host->mmc->ios.clock = 0;
			ms_host->mmc->ops->set_ios(ms_host->mmc, &ms_host->mmc->ios);
		}
		ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
		if (ret) {
			himci_error("failed to blockmux_set");
		}
	}


	if (ms_host->quirks & MSHCI_QUIRK_WLAN_DETECTION) {
		/* sdio power off */
		if (ms_host->mmc->ios.power_mode != MMC_POWER_OFF) {
			ret = mmc_sdio_suspend_ext(ms_host->mmc);
			if (ret) {
				printk("%s, sdio suspend error\n", __func__);
				return ret;
			}

			ms_host->mmc->ios.power_mode = MMC_POWER_UP;
			hi_host->old_timing = 0;
			hi_host->old_sig_voltage = 0;
		}
	}

    /*sd and emmc share the same suspend and resume*/
    mshci_suspend_host(ms_host, pm);

	spin_lock_irqsave(&ms_host->lock, flags);
	if(ms_host->clk_ref_counter == CLK_ENABLED){
		clk_disable(hi_host->pclk);
		ms_host->clk_ref_counter = CLK_DISABLED;
	}
	spin_unlock_irqrestore(&ms_host->lock, flags);


	return 0;
}
Esempio n. 29
0
static int __devinit hi_mci_probe(struct platform_device *pdev)
{
	struct mshci_host *ms_host = NULL;
	struct himci_host *hi_host = NULL;
	struct hisik3_mmc_platform_data *plat = NULL;
	struct resource *memres = NULL;


	int ret = 0, irq;
	int err;
	bool RetVal = 0;
	unsigned long flags;
	unsigned int sdcard_frequency = 0;



    #ifdef CONFIG_MACH_HI6620OEM
    if(1 == pdev->id)
    {
        raw_mmc_turn_on();
    }
    #endif

	himci_trace(HIMCI_TRACE_GEN_API, "++");

	himci_assert(pdev);

	plat = pdev->dev.platform_data;

	himci_trace(HIMCI_TRACE_SIGNIFICANT, "id:%d", pdev->id);

    /*通过读取硬件配置项,或者sdcard时钟配置,只需要SD卡流程走,走一遍*/
    #ifdef CONFIG_MACH_HI6620OEM

    if(1 == pdev->id)
    {
        RetVal = get_hw_config_int("sd_card/sdcard_frequency", &sdcard_frequency, NULL);

    	printk("hsad: sd_card/sdcard_frequency = %d, RetVal = %d\n", sdcard_frequency, RetVal);

        /*读取失败,配置默认值*/
    	if (RetVal == false) {
            printk(KERN_ERR "get board type failed.\n");
            g_sdcard_frequency = 90;
    	}

        /*如果获取配置值异常,则配置默认值*/
    	if ((sdcard_frequency != 100)&&(sdcard_frequency != 90)) {
            printk(KERN_ERR "sdcard_frequency %x is error.\n",sdcard_frequency);
            g_sdcard_frequency = 90;
    	}

    	g_sdcard_frequency = sdcard_frequency;
	}

    #endif

	/* 获取自己定义的数据 */
	if (!plat) {
		himci_error("Platform data not available");
		return -ENOENT;
	}
	if(0 == pdev->id)
	{
	     sema_init(&sem_to_rfile_sync_req,0);
	}

    /*创建硬件信号量IPC_SEM_EMMC*/
    if (0 == pdev->id) {
        mutex_lock(&emmc_mutex);
        emmc_sem_flag = 1;
        mutex_unlock(&emmc_mutex);
    }

	irq = platform_get_irq(pdev, 0);
	memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if ((!irq) || (!memres)) {
		himci_error("resource error");
		ret = -ENOENT;
        goto err_resource_get;
	}

	himci_trace(HIMCI_TRACE_SIGNIFICANT, "irq:%d,start:0x%x,size:0x%x", irq, \
										memres->start, resource_size(memres));

	ms_host = mshci_alloc_host(&pdev->dev, sizeof(struct himci_host));
	if (IS_ERR(ms_host)) {
		himci_error("mshci_alloc_host() failed\n");
		ret = PTR_ERR(ms_host);
        goto err_resource_get;
	}

	hi_host = mshci_priv(ms_host);
	hi_host->ms_host = ms_host;
	hi_host->pdev = pdev;
	hi_host->dev = &pdev->dev;
	hi_host->plat = plat;


	platform_set_drvdata(pdev, ms_host);

	/* MMC IP rstdis */
	if (plat->rstdis_mmc){
        ret = plat->rstdis_mmc();
        if ( ret < 0 ){
	        goto err_resource_get;
	    }
	}

    /* set emmc clk */

	hi_host->pclk = clk_get(&pdev->dev, plat->clk_mmc_low); /* work clk */

	if (IS_ERR(hi_host->pclk)) {
		himci_error("clk_get clk_mmc_low fail!");
		ret = PTR_ERR(hi_host->pclk);
		goto err_io_clk;
	}
	hi_host->clk_mmc_high= clk_get(&pdev->dev, plat->clk_mmc_high); /* highclk used for tuning */

    if (IS_ERR(hi_host->clk_mmc_high)) {
		himci_error("clk_get clk_mmc_high fail!");
		ret = PTR_ERR(hi_host->clk_mmc_high);
		goto err_io_clk;
	}

    ms_host->pclk = NULL;
    ms_host->clk_ref_counter = CLK_DISABLED;
    ms_host->clk_mmc_high = NULL;

	ms_host->pclk = hi_host->pclk;
	ms_host->clk_mmc_high = hi_host->clk_mmc_high;

	if (ret) {
	    himci_error("failed to clk_set_rate");
	}

    if(ms_host->clk_ref_counter == CLK_DISABLED){
        ret = clk_enable(hi_host->pclk);
        ms_host->clk_ref_counter = CLK_ENABLED;
        if (ret) {
            himci_error("clk_enable failed");
            ret = -ENOENT;
            goto err_clk_ops;
        }
    }



	ms_host->ioaddr = ioremap_nocache(memres->start, resource_size(memres));
	if (!ms_host->ioaddr) {
		himci_error("ioremap_nocache failed");
		ret = -ENXIO;
		goto err_req_regs;
	}

	ms_host->hw_name = "hisi_hi6620_mmc";
	ms_host->hw_mmc_id = hi_host->pdev->id;
	ms_host->ops = &mshci_hi_ops;
	ms_host->quirks = 0;
	ms_host->irq = irq;

	/* Setup quirks for the controller */

	if (plat->quirks) {
		ms_host->quirks |= plat->quirks;
	}

	if (plat->caps & MMC_CAP_CLOCK_GATING) {
		/* there is no reason not to use interral clock gating */
		ms_host->mmc->caps |= plat->caps;
		ms_host->mmc->caps |= MMC_CAP_CLOCK_GATING;
		ms_host->clock_gate = 1;
    } else {
		ms_host->mmc->caps |= plat->caps;
		ms_host->clock_gate = 0;
	}

	ms_host->mmc->caps2 = plat->caps2;

	/* sandisk card need clock longer than spec ask */
	/* sdcard also disable ip clock gate c00261379*/
	if (ms_host->hw_mmc_id == 0 || ms_host->hw_mmc_id == 1)
		ms_host->clock_gate = 0;

	if (plat->ocr_mask)
		ms_host->mmc->ocr_avail |= plat->ocr_mask;


    #ifdef CONFIG_MACH_HI6620OEM
    if (plat->iomux_name){
        hi_host->piomux_block = iomux_get_block(plat->iomux_name);
	    hi_host->pblock_config = iomux_get_blockconfig(plat->iomux_name);
    }

    /* todo requlator */
	if (plat->reg_name_ldo) {
		himci_trace(HIMCI_TRACE_SIGNIFICANT, "devname : %s, regname: %s",
					dev_name(hi_host->dev), plat->reg_name_ldo);
		hi_host->vcc_ldo = regulator_get(hi_host->dev, plat->reg_name_ldo);
		if (!IS_ERR(hi_host->vcc_ldo)) {
			/*
			 * Setup a notifier block to update this if another device
			 * causes the voltage to change
			 */
			hi_host->nb.notifier_call = &mshci_hi_disable_voltage;
			ret = regulator_register_notifier(hi_host->vcc_ldo, &hi_host->nb);
			if (ret) {
				dev_err(&pdev->dev,
					"regulator notifier request failed\n");
			}
		} else {
			dev_err(&pdev->dev, "regulator_get() failed\n");
			hi_host->vcc_ldo = NULL;
		}
	}

	if (plat->reg_name_lvs) {
		himci_trace(HIMCI_TRACE_SIGNIFICANT, "devname : %s, regname: %s",
					dev_name(hi_host->dev), plat->reg_name_lvs);
		hi_host->vcc_lvs = regulator_get(hi_host->dev, plat->reg_name_lvs);
		if (!IS_ERR(hi_host->vcc_lvs)) {
			/*
			 * Setup a notifier block to update this if another device
			 * causes the voltage to change
			 */
			hi_host->nb.notifier_call = &mshci_hi_disable_voltage;
			ret = regulator_register_notifier(hi_host->vcc_lvs, &hi_host->nb);
			if (ret) {
				dev_err(&pdev->dev,
					"regulator notifier request failed\n");
			}
		} else {
			dev_err(&pdev->dev, "regulator_get() failed\n");
			hi_host->vcc_lvs = NULL;
		}
	}
	hi_host->ocp_flag = 0;

	if (plat->signal_reg_name) {
		himci_trace(HIMCI_TRACE_SIGNIFICANT, "devname : %s, signal regname: %s",
						dev_name(hi_host->dev), plat->signal_reg_name);
		hi_host->signal_vcc = regulator_get(hi_host->dev, plat->signal_reg_name);
		if (IS_ERR(hi_host->signal_vcc)) {
			dev_err(&pdev->dev, "regulator_get() failed\n");
			hi_host->signal_vcc = NULL;
		}
	}
    #endif

	if( (1 == pdev->id)&&( (ms_host->quirks & MSHCI_QUIRK_CBP_DETECTION) == 0)) {
		ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
		if (ret) {
			himci_error("failed to blockmux_set");
		}
		mshci_sd_lowpower();
		if (hi_host->vcc_lvs){
			ret = regulator_enable(hi_host->vcc_lvs);
			if (ret) {
				himci_error("failed to regulator_enable LDO7");
			}
			ret = regulator_disable(hi_host->vcc_lvs);
			if (ret) {
			himci_error("failed to regulator_disable LDO7");
			}
		}
		udelay(30);
		if (hi_host->signal_vcc){
			ret = regulator_enable(hi_host->signal_vcc);
			if (ret) {
				himci_error("failed to regulator_enable LDO22");
			}
			ret = regulator_disable(hi_host->signal_vcc);
			if (ret) {
				himci_error("failed to regulator_disable LDO22");
			}
		}
	}else {/*for cbp*/
		ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
		if (ret) {
			himci_error("failed to blockmux_set");
		}

		if (hi_host->vcc_lvs){
			ret = regulator_enable(hi_host->vcc_lvs);
			if (ret) {
				himci_error("failed to regulator_enable LDO7");
			}
		}
		udelay(30);
		if (hi_host->signal_vcc){
			ret = regulator_enable(hi_host->signal_vcc);
			if (ret) {
				himci_error("failed to regulator_enable LDO22");
			}

			ret = regulator_disable(hi_host->signal_vcc);
			if (ret) {
				himci_error("failed to regulator_disable LDO22");
			}
		}
	}

	hi_host->old_sig_voltage = plat->default_signal_voltage;
	hi_host->old_timing = MMC_TIMING_UHS_DDR50;
	hi_host->timing_config = plat->timing_config;
	hi_host->allow_switch_signal_voltage = plat->allow_switch_signal_voltage;
	hi_host->suspend_timing_config = plat->suspend_timing_config;

	if (ms_host->quirks & MSHCI_QUIRK_WLAN_DETECTION) {
		ms_host->flags |= MSHCI_DEVICE_DEAD;
		ms_host->flags |= MMC_PM_KEEP_POWER;
		ms_host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
	}

	ret = mshci_add_host(ms_host);
	if (ret) {
		dev_err(&pdev->dev, "mshci_add_host() failed\n");
		goto err_add_host;
	}

	if (ms_host->quirks & MSHCI_QUIRK_WLAN_DETECTION) {
		ms_host->flags |= MSHCI_DEVICE_DEAD;
	        ms_host->flags |= MMC_PM_KEEP_POWER;
	        ms_host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
		if (plat->ext_cd_init)
			plat->ext_cd_init(&mshci_hi_notify_change);
		plat->set_power = mshci_hi_sdio_set_power;
	}

	if( (1 == pdev->id)&&( (ms_host->quirks & MSHCI_QUIRK_CBP_DETECTION) != 0)) {
	        ms_host->flags |= MMC_PM_KEEP_POWER;
	        ms_host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
	}


	if (ms_host->quirks & MSHCI_QUIRK_EXTERNAL_CARD_DETECTION) {

		err = gpio_request_one(plat->cd_gpio, GPIOF_IN, "ESDHC_CD");
		if (err) {
			dev_warn(mmc_dev(ms_host->mmc),
				"no card-detect pin available!\n");
			goto no_card_detect_pin;
		}
		/*SD_INT_FIX_suspend DTS:2013082704916 modifier: y00241633*/
		err = request_irq(gpio_to_irq(plat->cd_gpio), mshci_hi_card_detect_gpio,
				 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
				 mmc_hostname(ms_host->mmc), ms_host);
		if (err) {
			dev_warn(mmc_dev(ms_host->mmc), "request gpio irq error\n");
			goto no_card_detect_irq;
		}

        if ( plat->sw_gpio ){
            /* only sft has this gpio */
		    err = gpio_request_one(plat->sw_gpio, 0, "ESDHC_POWER_SWITCH");
		    if (err) {
			    dev_warn(mmc_dev(ms_host->mmc),
				    "no card-power-switch pin available!\n");
			    goto no_card_power_switch_pin;
		    }

            /*控制I/O口电平 1V8 or 3V3*/
            gpio_direction_output(plat->sw_gpio, 1);
        }

	}

	return 0;

no_card_power_switch_pin:
	plat->sw_gpio = err;
no_card_detect_irq:
	gpio_free(plat->cd_gpio);
no_card_detect_pin:
	plat->cd_gpio = err;
err_add_host:
	iounmap(ms_host->ioaddr);
	ms_host->ioaddr = NULL;
err_req_regs:
	spin_lock_irqsave(&ms_host->lock, flags);
	if(ms_host->clk_ref_counter == CLK_ENABLED){
		clk_disable(hi_host->pclk);
		ms_host->clk_ref_counter = CLK_DISABLED;
	}
	spin_unlock_irqrestore(&ms_host->lock, flags);
err_clk_ops:
    clk_put(hi_host->clk_mmc_high);
	clk_put(hi_host->pclk);
err_io_clk:
	mshci_free_host(ms_host);

err_resource_get:

	return ret;
}
Esempio n. 30
0
void mshci_hi_set_ios(struct mshci_host *ms_host, struct mmc_ios *ios)
{
	struct himci_host * hi_host = (struct himci_host *)(ms_host->private);
	int ret = -1;
	int cbp_flag = 0;

	hi_host_trace(HIMCI_TRACE_GEN_API, "++");

	himci_assert(ios);
	himci_assert(hi_host);

	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->power_mode = %d ", ios->power_mode);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->clock = %d ", ios->clock);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->bus_width = %d ", ios->bus_width);
	hi_host_trace(HIMCI_TRACE_GEN_INFO, "ios->timing = %d ", ios->timing);

	ret = get_hw_config_int("modem/viacbp82d", &cbp_flag, NULL);
	if ((!ret) || (0 == cbp_flag)) {
		pr_info("%s has no cbp support\n", __func__);
	}

	pr_info("%s mode %d\n", __func__, ios->power_mode);

	/* process power */
	if (hi_host->old_power_mode != ios->power_mode) {
		switch (ios->power_mode) {
		case MMC_POWER_OFF:
			if ((!cbp_flag)&&(1 == ms_host->hw_mmc_id)){
				mshci_sd_power_onoff(ms_host, 0);
				break;
			}
			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to lowpower");
			if (hi_host->piomux_block && hi_host->pblock_config){
				ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, LOWPOWER);
					if (ret) {
						himci_error("failed to blockmux_set");
					}
			}

			if (hi_host->vcc_lvs){
				ret = regulator_disable(hi_host->vcc_lvs);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
			}

			if (hi_host->vcc_ldo){
				ret = regulator_disable(hi_host->vcc_ldo);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
			}
			break;
		case MMC_POWER_UP:

			hi_host_trace(HIMCI_TRACE_SIGNIFICANT, "set io to normal");
			if ((!cbp_flag)&&(1 == ms_host->hw_mmc_id)){
				mshci_sd_power_onoff(ms_host, 1);
				break;
			}
			if (hi_host->vcc_ldo){
				ret = regulator_enable(hi_host->vcc_ldo);
				if (ret) {
					himci_error("failed to regulator_enable");
				}
			}
			if((1 == hi_host->ms_host->hw_mmc_id)&&(cbp_flag)){
				/*cbp need set as fixed 1.8v*/
				himci_error("sdio regulator_set_voltage 1.8 \n");
				if (hi_host->vcc_lvs) {
					ret = regulator_set_voltage(hi_host->vcc_lvs, SDMMC_1V8_IO_LDO7_180, SDMMC_1V8_IO_LDO7_180);
					if (ret != 0) {
						himci_error("failed to LDO7 regulator_set_voltage 1.8 \n");
					}
				}
			}
            if (hi_host->vcc_lvs){
                    ret = regulator_enable(hi_host->vcc_lvs);
                if (ret) {
                    himci_error("failed to regulator_enable");
                }
            }
            

            if (hi_host->piomux_block && hi_host->pblock_config){
                ret = blockmux_set(hi_host->piomux_block, hi_host->pblock_config, NORMAL);
                if (ret) {
                    himci_error("failed to blockmux_set");
                }
            }
			break;
		case MMC_POWER_ON:
			break;
		default:
			himci_error("unknown power supply mode");
			break;
		}
		hi_host->old_power_mode = ios->power_mode;
	}

	hi_host_trace(HIMCI_TRACE_GEN_API, "--");
}