static int rk29_adc_read(struct adc_host *adc)
{
	struct rk29_adc_device *dev  = adc_priv(adc);

	udelay(SAMPLE_RATE);
	return readl(dev->regs + ADC_DATA) & ADC_DATA_MASK;
}
예제 #2
0
static void rk30_adc_dump(struct adc_host *adc)
{
	struct rk30_adc_device *dev  = adc_priv(adc);

        dev_info(adc->dev, "[0x00-0x0c]: 0x%08x 0x%08x 0x%08x 0x%08x\n",
                        adc_readl(dev->regs + 0x00),
                        adc_readl(dev->regs + 0x04),
                        adc_readl(dev->regs + 0x08),
                        adc_readl(dev->regs + 0x0c));
}
예제 #3
0
static void rk30_adc_start(struct adc_host *adc)
{
	struct rk30_adc_device *dev  = adc_priv(adc);
	int chn = adc->chn;

	//adc_writel(0, dev->regs + ADC_CTRL);
        adc_writel(0x08, dev->regs + ADC_DELAY_PU_SOC);
	adc_writel(ADC_CTRL_POWER_UP|ADC_CTRL_CH(chn)|ADC_CTRL_IRQ_ENABLE, dev->regs + ADC_CTRL);

	return;
}
static void rk29_adc_start(struct adc_host *adc)
{
	struct rk29_adc_device *dev  = adc_priv(adc);
	int chn = adc->cur->chn;

	writel(0, dev->regs + ADC_CTRL);
	writel(ADC_CTRL_POWER_UP|ADC_CTRL_CH(chn), dev->regs + ADC_CTRL);
	udelay(SAMPLE_RATE);

	writel(readl(dev->regs + ADC_CTRL)|ADC_CTRL_IRQ_ENABLE|ADC_CTRL_START, 
		dev->regs + ADC_CTRL);
	return;
}
static void rk29_adc_stop(struct adc_host *adc)
{
	struct rk29_adc_device *dev  = adc_priv(adc);
	
	writel(0, dev->regs + ADC_CTRL);
}
static int rk29_adc_probe(struct platform_device *pdev)
{
	struct adc_host *adc = NULL;
	struct rk29_adc_device *dev;
	struct resource *res;
	int ret;

	adc = adc_alloc_host(sizeof(struct rk29_adc_device), &pdev->dev);
	if (!adc)
		return -ENOMEM;
	spin_lock_init(&adc->lock);
	adc->dev = &pdev->dev;
	adc->is_suspended = 0;
	adc->ops = &rk29_adc_ops;
	dev = adc_priv(adc);
	dev->adc = adc;
	dev->irq = platform_get_irq(pdev, 0);
	if (dev->irq <= 0) {
		dev_err(&pdev->dev, "failed to get adc irq\n");
		ret = -ENOENT;
		goto err_alloc;
	}

	ret = request_irq(dev->irq, rk29_adc_irq, 0, pdev->name, dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to attach adc irq\n");
		goto err_alloc;
	}
	dev->clk = clk_get(&pdev->dev, "saradc");
	if (IS_ERR(dev->clk)) {
		dev_err(&pdev->dev, "failed to get adc clock\n");
		ret = PTR_ERR(dev->clk);
		goto err_irq;
	}

	ret = clk_set_rate(dev->clk, ADC_CLK_RATE * 1000 * 1000);
	if(ret < 0) {
		dev_err(&pdev->dev, "failed to set adc clk\n");
		goto err_clk;
	}
	clk_enable(dev->clk);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "cannot find IO resource\n");
		ret = -ENOENT;
		goto err_clk;
	}
	dev->ioarea = request_mem_region(res->start, (res->end - res->start) + 1, 
									pdev->name);
	if(dev->ioarea == NULL) {
		dev_err(&pdev->dev, "cannot request IO\n");
		ret = -ENXIO;
		goto err_clk;
	}
	dev->regs = ioremap(res->start, (res->end - res->start) + 1);
	if (!dev->regs) {
		dev_err(&pdev->dev, "cannot map IO\n");
		ret = -ENXIO;
		goto err_ioarea;
	}
	platform_set_drvdata(pdev, dev);
	dev_info(&pdev->dev, "rk29 adc: driver initialized\n");
	return 0;
// err_iomap:
//	iounmap(dev->regs);

 err_ioarea:
	release_resource(dev->ioarea);
	kfree(dev->ioarea);
	clk_disable(dev->clk);

 err_clk:
	clk_put(dev->clk);

 err_irq:
	free_irq(dev->irq, dev);

 err_alloc:
	adc_free_host(dev->adc);
	return ret;
}
예제 #7
0
static int rk30_adc_read(struct adc_host *adc)
{
	struct rk30_adc_device *dev  = adc_priv(adc);

	return adc_readl(dev->regs + ADC_DATA) & ADC_DATA_MASK;
}
예제 #8
0
static int rk30_adc_probe(struct platform_device *pdev)
{
        struct adc_platform_data *pdata = pdev->dev.platform_data;
	struct adc_host *adc = NULL;
	struct rk30_adc_device *dev;
	struct resource *res;
	int ret = 0, i, v;

        if(!pdata)
                return -EINVAL;

	adc = adc_alloc_host(&pdev->dev, sizeof(struct rk30_adc_device), SARADC_CHN_MASK);
	if (!adc)
		return -ENOMEM;
	adc->ops = &rk30_adc_ops;
        adc->pdata = pdata;
	dev = adc_priv(adc);
	dev->adc = adc;
	dev->irq = platform_get_irq(pdev, 0);
	if (dev->irq <= 0) {
		dev_err(&pdev->dev, "failed to get adc irq\n");
		ret = -ENOENT;
		goto err_alloc;
	}

	ret = request_threaded_irq(dev->irq, NULL, rk30_adc_irq, IRQF_ONESHOT, pdev->name, dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to attach adc irq\n");
		goto err_alloc;
	}

	dev->pclk = clk_get(&pdev->dev, "pclk_saradc");
	if (IS_ERR(dev->pclk)) {
		dev_err(&pdev->dev, "failed to get adc pclk\n");
		ret = PTR_ERR(dev->pclk);
		goto err_irq;
	}
	clk_enable(dev->pclk);

	dev->clk = clk_get(&pdev->dev, "saradc");
	if (IS_ERR(dev->clk)) {
		dev_err(&pdev->dev, "failed to get adc clock\n");
		ret = PTR_ERR(dev->clk);
		goto err_pclk;
	}

	ret = clk_set_rate(dev->clk, ADC_CLK_RATE * 1000 * 1000);
	if(ret < 0) {
		dev_err(&pdev->dev, "failed to set adc clk\n");
		goto err_clk2;
	}
	clk_enable(dev->clk);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "cannot find IO resource\n");
		ret = -ENOENT;
		goto err_clk;
	}
	dev->ioarea = request_mem_region(res->start, (res->end - res->start) + 1, 
									pdev->name);
	if(dev->ioarea == NULL) {
		dev_err(&pdev->dev, "cannot request IO\n");
		ret = -ENXIO;
		goto err_clk;
	}
	dev->regs = ioremap(res->start, (res->end - res->start) + 1);
	if (!dev->regs) {
		dev_err(&pdev->dev, "cannot map IO\n");
		ret = -ENXIO;
		goto err_ioarea;
	}
        g_adc = adc;
	platform_set_drvdata(pdev, dev);

        if(adc->pdata->base_chn > 0){
                adc->base_client = adc_register(adc->pdata->base_chn, NULL, NULL);
                if(!adc->base_client){
		        dev_err(&pdev->dev, "adc_register(base_chn: %d) failed\n", adc->pdata->base_chn);
                        ret = -ENOMEM;
                        goto err_adc_register;
                }
                for(i = 0; i < SAMPLE_COUNT; i++){
                        v = adc_sync_read(adc->base_client);
                        if(v < 0){
		                dev_err(&pdev->dev, "adc_register(base_chn: %d) failed\n", adc->pdata->base_chn);
                                ret = v;
                                goto err_adc_sync_read;
                        }else if(v < MIN_SAMPLE_VALUE){
		                dev_info(&pdev->dev, "chn[%d]: adc value(%d) is invalide\n", adc->pdata->base_chn, v);
                                adc_unregister(adc->base_client);
                                adc->base_client = NULL;
                                break;
                        }
                        adc_dbg(&pdev->dev, "read ref_adc: %d\n", v);
                        mdelay(1);
                }
        }
	dev_info(&pdev->dev, "rk30 adc: driver initialized\n");
	return 0;
err_adc_sync_read:
        adc_unregister(adc->base_client);
        adc->base_client = NULL;
err_adc_register:
	iounmap(dev->regs);
err_ioarea:
	release_resource(dev->ioarea);
	kfree(dev->ioarea);

err_clk:
	clk_disable(dev->clk);

err_pclk:
	clk_disable(dev->pclk);
	clk_put(dev->pclk);

err_clk2:
	clk_put(dev->clk);

err_irq:
	free_irq(dev->irq, dev);

err_alloc:
        adc_free_host(dev->adc);
	return ret;
}