Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bc618e8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: fsm_rfic: Fix PDM and config gpio"

parents 3318fc66 28fb7c5a
Loading
Loading
Loading
Loading
+266 −87
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/ssbi.h>
#include <linux/clk.h>
#include <mach/msm_iomap.h>
#include <mach/gpiomux.h>
#include <mach/board.h>
@@ -48,6 +49,7 @@
 * FTR8700, WTR1605  RFIC
 */

#define RFIC_MTR_DEVICE_NUM		5
#define RFIC_DEVICE_NUM			9
#define RFIC_GRFC_REG_NUM		6

@@ -67,6 +69,8 @@
#define FTR2_SBI_SEL0			105
#define FTR2_SBI_SEL1			106

#define PDM_1_0_CTL	0x0000
#define PDM_1_1_CTL	0x1000
#define PDM_1_2_CTL	0x2000
#define PDM_2_0_CTL	0x4000
#define PDM_2_1_CTL	0x5000
@@ -74,6 +78,7 @@
#define PDM_OE		1
#define PDM_BYTE	0x80
#define PDM_WORD	0x8000
#define MSM_MAX_GPIO    32

uint8_t rfbid;
void __iomem *grfc_base;
@@ -81,6 +86,7 @@ void __iomem *pdm_base;
/*
 * Device private information per device node
 */
struct mutex rficlock;

static struct ftr_dev_node_info {
	void *grfcctrladdr;
@@ -159,7 +165,8 @@ static long ftr_ioctl(struct file *file,

		    mutex_lock(&pdev->lock);

		    if ((pdfi->ftrid == 2) || (pdfi->ftrid == 3)) {
		    if (((pdfi->ftrid == 2) || (pdfi->ftrid == 3))
				&& (rfbid < RF_TYPE_48)) {
			__raw_writel(
				pdev->busselect[RFIC_FTR_GET_BUS(rficaddr)],
				pdev->grfcctrladdr);
@@ -194,7 +201,8 @@ static long ftr_ioctl(struct file *file,

		    mutex_lock(&pdev->lock);

		    if ((pdfi->ftrid == 2) || (pdfi->ftrid == 3)) {
		    if (((pdfi->ftrid == 2) || (pdfi->ftrid == 3))
				&& (rfbid < RF_TYPE_48)) {
			__raw_writel(
				pdev->busselect[RFIC_FTR_GET_BUS(rficaddr)],
				pdev->grfcctrladdr);
@@ -220,11 +228,13 @@ static long ftr_ioctl(struct file *file,

			if (copy_from_user(&param, argp, sizeof(param)))
				return -EFAULT;

			rficaddr = param.rficaddr;

			mutex_lock(&pdev->lock);

		    if ((pdfi->ftrid == 2) || (pdfi->ftrid == 3)) {
			if (((pdfi->ftrid == 2) || (pdfi->ftrid == 3))
				&& (rfbid < RF_TYPE_48)) {
				__raw_writel(
				pdev->busselect[RFIC_FTR_GET_BUS(rficaddr)],
				pdev->grfcctrladdr);
@@ -246,6 +256,58 @@ static long ftr_ioctl(struct file *file,
		}
		break;

	case RFIC_IOCTL_GPIO_SETTING:
		{
			struct rfic_gpio_param param;
			struct msm_gpiomux_config rf_config[MSM_MAX_GPIO];
			struct gpiomux_setting rf_setting[MSM_MAX_GPIO];
			struct gpio_alt_config *alt_config;
			int gp_size, i;
			void *pGP;

			if (pdfi->ftrid != 0)
				return -EINVAL;

			if (copy_from_user(&param, argp, sizeof(param))) {
				pr_err("%s: cfu fail for param\n", __func__);
				return -EFAULT;
			}

			if ((param.num < 1) || (param.num > MSM_MAX_GPIO)) {
				pr_err("Invalid GPIO count %d\n", param.num);
				return -EINVAL;
			}

			gp_size = sizeof(struct gpio_alt_config) * param.num;

			pGP = kmalloc(gp_size, GFP_KERNEL);
			if (pGP == NULL)
				return -ENOMEM;

			if (copy_from_user(pGP, param.pArray, gp_size)) {
				pr_err("%s: cfu fail for pGP\n", __func__);
				kfree(pGP);
				return -EFAULT;
			}

			alt_config = (struct gpio_alt_config *)pGP;
			for (i = 0; i < param.num; i++) {
				rf_config[i].gpio = (unsigned)alt_config->gpio;
				rf_setting[i].func = alt_config->func;
				rf_setting[i].drv = alt_config->drv;
				rf_setting[i].pull = alt_config->pull;
				rf_setting[i].dir = alt_config->dir;
				rf_config[i].settings[GPIOMUX_ACTIVE] =
					&rf_setting[i];
				rf_config[i].settings[GPIOMUX_SUSPENDED] =
					&rf_setting[i];
				alt_config++;
			}
			msm_gpiomux_install(rf_config, param.num);
			kfree(pGP);
		}
		break;

	case RFIC_IOCTL_GET_GRFC:
		{
			struct rfic_grfc_param param;
@@ -330,6 +392,7 @@ static long ftr_ioctl(struct file *file,

			if (copy_from_user(&param, argp, sizeof(param)))
				return -EFAULT;

			pdmaddr = (unsigned int)pdm_base + param.offset;
			value = (u8) param.value;

@@ -374,7 +437,6 @@ uint8_t rf_interface_id(void)
	tempid = gpio_get_value(FTR2_SBI_SEL1);
	rfbid |= tempid;

	pr_info("%s: RF Board Id 0x%x\n", __func__, rfbid);
	return rfbid;
}

@@ -435,6 +497,34 @@ struct miscdevice ftr_misc_dev[RFIC_DEVICE_NUM] = {
	},
};

struct miscdevice mtr_misc_dev[RFIC_MTR_DEVICE_NUM] = {
	{
		.minor = MISC_DYNAMIC_MINOR,
		.name = GRFC_DEVICE_NAME,
		.fops = &ftr_fops,
	},
	{
		.minor = MISC_DYNAMIC_MINOR,
		.name = PDM_DEVICE_NAME,
		.fops = &ftr_fops,
	},
	{
		.minor = MISC_DYNAMIC_MINOR,
		.name = RFIC_MTR_DEVICE_NAME "0",
		.fops = &ftr_fops,
	},
	{
		.minor = MISC_DYNAMIC_MINOR,
		.name = RFIC_MTR_DEVICE_NAME "1",
		.fops = &ftr_fops,
	},
	{
		.minor = MISC_DYNAMIC_MINOR,
		.name = RFIC_WGR_DEVICE_NAME,
		.fops = &ftr_fops,
	},
};

int ftr_find_id(int minor)
{
	int i;
@@ -536,35 +626,29 @@ static int wtr_regulator_init(struct platform_device *pdev)

static int mantaray_regulator_init(struct platform_device *pdev)
{
	int ret;
	struct regulator *vreg_ldo26;

	vreg_ldo26 = regulator_get(&pdev->dev, "vdd-mtr");
	if (IS_ERR(vreg_ldo26)) {
		pr_err("%s: vreg get l26-reg failed (%ld)\n",
			__func__, PTR_ERR(vreg_ldo26));
		return PTR_ERR(vreg_ldo26);
	return 0;
}

	ret = regulator_set_optimum_mode(vreg_ldo26, 250000);
	if (ret)
		pr_err("%s: unable to set optimum mode for ldo26\n", __func__);

	ret = regulator_enable(vreg_ldo26);
	if (ret) {
		pr_err("%s: unable to enable ldo26 voltage\n", __func__);
		return PTR_ERR(vreg_ldo26);
static void pdm_enable(void)
{
	__raw_writel(PDM_OE, pdm_base + PDM_1_2_CTL);
	__raw_writel(PDM_OE, pdm_base + PDM_2_0_CTL);
	__raw_writel(PDM_OE, pdm_base + PDM_2_1_CTL);
	__raw_writel(PDM_OE, pdm_base + PDM_2_2_CTL);
}

	return 0;
}

static void pdm_enable(void)
void pdm_mtr_enable(void)
{
	__raw_writel(PDM_OE, pdm_base + PDM_1_2_CTL);
	__raw_writel(0xb200, pdm_base + PDM_1_2_CTL + 4);
	__raw_writel(PDM_OE, pdm_base + PDM_2_0_CTL);
	__raw_writel(0xb200, pdm_base + PDM_2_0_CTL + 4);
	__raw_writel(PDM_OE, pdm_base + PDM_2_1_CTL);
	__raw_writel(0xb2, pdm_base + PDM_2_1_CTL + 4);
	__raw_writel(PDM_OE, pdm_base + PDM_2_2_CTL);
	__raw_writel(0xb200, pdm_base + PDM_2_2_CTL + 4);
}


@@ -573,47 +657,125 @@ static int ftr_probe(struct platform_device *pdev)
	struct device_node *np = pdev->dev.of_node;
	struct ftr_dev_node_info *ptr;
	struct resource *mem_res;
	struct clk *pdm_clk;
	int ret;
	u8 version = 0;

	pr_debug("%s: me = %p, parent = %p\n",
		__func__, pdev, pdev->dev.parent);

	mutex_lock(&rficlock);

	if (nDev >= RFIC_DEVICE_NUM) {
		pr_warn("%s: Invalid devices %d\n", __func__, nDev);
		mutex_unlock(&rficlock);
		return -EINVAL;
	}

	if (!nDev) {
		rfbid = rf_interface_id();
		rfbid = rfbid & RF_TYPE_48;
		pr_info("%s: RF Board Type 0x%x\n", __func__, rfbid);

		switch (rfbid) {
		case RF_TYPE_16:
			ftr_regulator_init(pdev);
			wtr_regulator_init(pdev);
			break;
		case RF_TYPE_32:
			ftr_regulator_init(pdev);
			break;
		case RF_TYPE_48:
			mantaray_regulator_init(pdev);
			break;
		default:
			pr_warn("%s:Regulators may not be turned ON %d\n",
					__func__, rfbid);
		}

		rfbid = rf_interface_id();
		pr_info("%s: RF Board Id 0x%x\n", __func__, rfbid);

		switch (rfbid) {
		case RF_TYPE_33:
			fsm9900_gluon_init();
			ftr_regulator_init(pdev);
			break;
		case RF_TYPE_17:
		case RF_TYPE_18:
			fsm9900_rfic_init();
			ftr_regulator_init(pdev);
			wtr_regulator_init(pdev);
			break;
		case RF_TYPE_49:
			fsm9900_rfic_init();
			ftr_regulator_init(pdev);
			mantaray_regulator_init(pdev);
			break;
		default:
			pr_warn("%s:Unidentified board\n", __func__);
			pr_warn("%s:Regulators may not be turned ON\n",
					__func__);
			pr_warn("%s:GPIOs not configured %d\n",
					__func__, rfbid);
		}

		mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		grfc_base = devm_ioremap_resource(&pdev->dev, mem_res);
		if (IS_ERR(grfc_base))
		if (IS_ERR(grfc_base)) {
			mutex_unlock(&rficlock);
			return PTR_ERR(grfc_base);
		}
		ret = device_create_file(&pdev->dev, &dev_attr_rfboard_id);
		WARN_ON(ret);
	} else if ((nDev == 1) && (rfbid & RF_TYPE_16)) {

	} else if ((nDev == 1) && (rfbid > RF_TYPE_48)) {
		mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		pdm_base = devm_ioremap_resource(&pdev->dev, mem_res);
		if (IS_ERR(pdm_base)) {
			mutex_unlock(&rficlock);
			return PTR_ERR(pdm_base);
		}
		pdm_clk = clk_get(&pdev->dev, "ahb_clk");
		if (IS_ERR(pdm_clk)) {
			pdm_clk = NULL;
			pr_err("%s: AHB CLK is  NULL\n", __func__);
		} else {
			pr_debug("%s: AHB CLK is  0x%x\n", __func__,
				(unsigned int)pdm_clk);
			clk_prepare(pdm_clk);
			clk_enable(pdm_clk);
		}

		pdm_clk = clk_get(&pdev->dev, "pdm2_clk");
		if (IS_ERR(pdm_clk)) {
			pdm_clk = NULL;
			pr_err("%s: PDM2 CLK is  NULL\n", __func__);
		} else {
			pr_debug("%s: PDM2 CLK is  0x%x\n", __func__,
				(unsigned int)pdm_clk);
			clk_prepare(pdm_clk);
			clk_enable(pdm_clk);
		}

		pdm_mtr_enable();
		pr_info("%s: MTR PDM Enabled\n", __func__);
	} else if ((nDev == 1) && (rfbid > RF_TYPE_16) &&
			(rfbid < RF_TYPE_32)) {
		mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		pdm_base = devm_ioremap_resource(&pdev->dev, mem_res);
		if (IS_ERR(pdm_base))
		if (IS_ERR(pdm_base)) {
			mutex_unlock(&rficlock);
			return PTR_ERR(pdm_base);
		}

		pdm_clk = clk_get(&pdev->dev, "ahb_clk");
		if (IS_ERR(pdm_clk)) {
			pdm_clk = NULL;
			pr_err("%s: AHB CLK is  NULL\n", __func__);
		} else {
			clk_prepare(pdm_clk);
			clk_enable(pdm_clk);
		}

		pdm_clk = clk_get(&pdev->dev, "pdm2_clk");
		if (IS_ERR(pdm_clk)) {
			pdm_clk = NULL;
			pr_err("%s: PDM2 CLK is  NULL\n", __func__);
		} else {
			clk_prepare(pdm_clk);
			clk_enable(pdm_clk);
		}

		pdm_enable();
		pr_info("%s: PDM Enabled\n", __func__);
	}
@@ -652,15 +814,27 @@ static int ftr_probe(struct platform_device *pdev)

	mutex_init(&ptr->lock);

	if (rfbid < RF_TYPE_48) {
		ret = misc_register(ftr_misc_dev + nDev);

		if (ret < 0) {
			misc_deregister(ftr_misc_dev + nDev);
			mutex_unlock(&rficlock);
			return ret;
		}
	} else {
		ret = misc_register(mtr_misc_dev + nDev);

		if (ret < 0) {
			misc_deregister(mtr_misc_dev + nDev);
			mutex_unlock(&rficlock);
			return ret;
		}
	}

	nDev++;
	pr_info("%s: num_of_ssbi_devices = %d\n", __func__, nDev);
	mutex_unlock(&rficlock);

	return of_platform_populate(np, NULL, NULL, &pdev->dev);
}
@@ -670,9 +844,13 @@ static int ftr_remove(struct platform_device *pdev)
{
	int i;

	if (rfbid < RF_TYPE_48) {
		for (i = 0; i < RFIC_DEVICE_NUM; ++i)
			misc_deregister(ftr_misc_dev + i);

	} else {
		for (i = 0; i < RFIC_MTR_DEVICE_NUM; ++i)
			misc_deregister(mtr_misc_dev + i);
	}
	return 0;
}

@@ -697,6 +875,7 @@ int __init ftr_init(void)
	int rc;

	nDev = 0;
	mutex_init(&rficlock);
	pr_debug("%s: rfic-fsm9900 driver init\n",  __func__);
	rc = platform_driver_register(&ftr_driver);
	return rc;