Пример #1
0
/*
  set pin configuration at run time
  caller fills pin_configuration, except sel, which will derived from func in this routine.
*/
int pinmux_set_pin_config(struct pin_config *config)
{
	int ret = 0, i;
	void __iomem *base = g_chip_pin_desc.base;
	enum PIN_NAME name;

	if(!config)
		return -EINVAL;
	name = config->name;
	if(!is_ball_valid(name))
		return -EINVAL;

	/* get the sel bits */
	for (i=0; i<MAX_ALT_FUNC; i++) {
		if (g_chip_pin_desc.desc_tbl[name].f_tbl[i] == config->func) {
			config->reg.b.sel = i;
			break;
		}
	}
	if (i==MAX_ALT_FUNC) {
		printk (KERN_WARNING "%s no matching function for pin %u\n", __func__, config->name);
		return -EINVAL;
	}

	writel(config->reg.val, base + g_chip_pin_desc.desc_tbl[name].reg_offset);

	/*
	 * When CONFIG_CAPRI_BSC3_PAD_CTRL_MODE is enabled, BSC3 pins are set
	 * to GPIO_67 and GPIO_68, if there is no I2C traffic on BSC3. This
	 * would pump lots of  PINMUX change message to the console. So here
	 * use pr_debug instead of pr_info.
	 */
#ifndef CONFIG_CAPRI_BSC3_PAD_CTRL_MODE
	pr_info("[PINMUX] - write value 0x%08x to register 0x%08x\n",
		config->reg.val,
		g_chip_pin_desc.desc_tbl[name].reg_offset);
#else
	pr_debug("[PINMUX] - write value 0x%08x to register 0x%08x\n",
		config->reg.val,
		g_chip_pin_desc.desc_tbl[name].reg_offset);
#endif


#ifdef CONFIG_PINMUX_VERIFY_WRITE
/* Add PINMUX_VERIFY_WRITE to the boards.cfg file board of interest to enable this code */
	{
		unsigned int rdval = readl(base + g_chip_pin_desc.desc_tbl[name].reg_offset);
		if (rdval != config->reg.val)
		{
			printf(KERN_ERR "%s: pin %u  offset 0x%x  wrote 0x%x  rdval 0x%x\n", 	
			__func__, name, g_chip_pin_desc.desc_tbl[name].reg_offset,
			config->reg.val, rdval); 

			return -EIO;
		}
	}	
#endif
	return ret;
}
Пример #2
0
/*
  get pin configuration at run time
  caller provides pin ball name
*/
int pinmux_get_pin_config(struct pin_config *config)
{
	int ret = 0;
	void __iomem *base = g_chip_pin_desc.base;
	enum PIN_NAME name;

	if(!config)
		return -EINVAL;
	name = config->name;
	if(!is_ball_valid(name))
		return -EINVAL;

	config->reg.val = readl(base+g_chip_pin_desc.desc_tbl[name].reg_offset);

	/* populate func */
	config->func = g_chip_pin_desc.desc_tbl[name].f_tbl[config->reg.b.sel];

	return ret;
}
static int bcm_modem_detect_gpio_request(enum PIN_NAME pin_cfg_name,
		enum PIN_FUNC pin_cfg_func)
{
	int rc = 0;
	struct pin_config modem_det_pin_cfg;
	struct pin_config modem_det_pin_cfg_orig;
	unsigned int gpio_pin;
	enum PIN_FUNC pin_func_orig;

	if (is_ball_valid(pin_cfg_name)) {

		rc = pinmux_find_gpio(pin_cfg_name, &gpio_pin, &pin_func_orig);
		if (rc < 0) {
			pr_err("%s: Unable to find gpio pin\n", __func__);
			return rc;
		}

		modem_det_pin_cfg.name = pin_cfg_name;
		rc = pinmux_get_pin_config(&modem_det_pin_cfg);
		if (rc < 0) {
			pr_err("%s: Unable to find pin configuration\n",
					__func__);
			return rc;
		}

		/* Keep a copy of original configuration */
		memcpy(&modem_det_pin_cfg_orig, &modem_det_pin_cfg,
									sizeof(struct pin_config));

		modem_det_pin_cfg.reg.b.pull_up = 1;
		modem_det_pin_cfg.reg.b.pull_dn = 0;
		modem_det_pin_cfg.reg.b.drv_sth = DRIVE_STRENGTH_16MA;
		modem_det_pin_cfg.func = pin_cfg_func;

		rc = pinmux_set_pin_config(&modem_det_pin_cfg);
		if (rc < 0) {
			pr_err("%s: Unable to set pin configuration\n",
					__func__);
			return rc;
		}

		rc = gpio_request(gpio_pin, "modem_detect");
		if (rc < 0) {
			pr_err("Unable to request GPIO pin %d\n",
					gpio_pin);
			goto modem_detect_pin_config_restore;
		}

		/* Set to output to charge potentially existing capacitor */
		gpio_direction_output(gpio_pin, 1);

		mdelay(BCM_MODEM_DETECT_GPIO_CHARGE_MS);

		gpio_direction_input(gpio_pin);

		modem_present = gpio_get_value(gpio_pin);

modem_detect_pin_config_restore:
		gpio_free(gpio_pin);
		pinmux_set_pin_config(&modem_det_pin_cfg_orig);

	} else {
		rc = -EINVAL;
		pr_err("%s: Invalid gpio pin name provided %d\n",
				__func__, pin_cfg_name);
	}

	return rc;
}