Ejemplo n.º 1
0
static int __init magician_init(void)
{
	int ret;
	struct i2c_adapter *adapter;
	struct i2c_client *client;

	if (!machine_is_magician())
		return -ENODEV;

	adapter = i2c_get_adapter(0);
	if (!adapter)
		return -ENODEV;
	client = i2c_new_device(adapter, i2c_board_info);
	i2c_put_adapter(adapter);
	if (!client)
		return -ENODEV;

	ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER");
	if (ret)
		goto err_request_spk;
	ret = gpio_request(EGPIO_MAGICIAN_EP_POWER, "EP_POWER");
	if (ret)
		goto err_request_ep;
	ret = gpio_request(EGPIO_MAGICIAN_MIC_POWER, "MIC_POWER");
	if (ret)
		goto err_request_mic;
	ret = gpio_request(EGPIO_MAGICIAN_IN_SEL0, "IN_SEL0");
	if (ret)
		goto err_request_in_sel0;
	ret = gpio_request(EGPIO_MAGICIAN_IN_SEL1, "IN_SEL1");
	if (ret)
		goto err_request_in_sel1;

	gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0);

	magician_snd_device = platform_device_alloc("soc-audio", -1);
	if (!magician_snd_device) {
		ret = -ENOMEM;
		goto err_pdev;
	}

	platform_set_drvdata(magician_snd_device, &magician_snd_devdata);
	magician_snd_devdata.dev = &magician_snd_device->dev;
	ret = platform_device_add(magician_snd_device);
	if (ret) {
		platform_device_put(magician_snd_device);
		goto err_pdev;
	}

	return 0;

err_pdev:
	gpio_free(EGPIO_MAGICIAN_IN_SEL1);
err_request_in_sel1:
	gpio_free(EGPIO_MAGICIAN_IN_SEL0);
err_request_in_sel0:
	gpio_free(EGPIO_MAGICIAN_MIC_POWER);
err_request_mic:
	gpio_free(EGPIO_MAGICIAN_EP_POWER);
err_request_ep:
	gpio_free(EGPIO_MAGICIAN_SPK_POWER);
err_request_spk:
	return ret;
}
Ejemplo n.º 2
0
int msm_camera_flash_led(
		struct msm_camera_sensor_flash_external *external,
		unsigned led_state)
{
#ifdef CONFIG_IMX175
#if defined(CONFIG_MACH_MELIUS)
	int i = 0;
#endif
	int rc = 0;
	if(Torch_On == true) {
		cam_err("[Assistive Light On!!\n");
		return 0;
	}	
#if defined(CONFIG_MACH_MELIUS)
	/* FLASH IC : KTD2692 */
	cam_err("[led_state::%d]\n", led_state);
	switch (led_state) {
	case MSM_CAMERA_LED_INIT:
		cam_err("[MSM_CAMERA_LED_INIT]\n");
#if defined(CONFIG_MACH_CRATER_CHN_CTC) || defined(CONFIG_MACH_MELIUS_VZW) || defined(CONFIG_MACH_MELIUS_SPR) || defined(CONFIG_MACH_MELIUS_USC)
		if (system_rev < 0X01) {
#else
		if (system_rev < 0x07) {
#endif
			set_gpio_ENF(external, false);
		} else {
			/* Disable Cutoff Low voltage */
			KTD2692_ctrl_cmd(external, LVP_SETTING | 0x00);
			/*D2692_ctrl_cmd(external, MODE_CONTROL | 0x00);*/
		}
		break;

	case MSM_CAMERA_LED_RELEASE:
		cam_err("[MSM_CAMERA_LED_RELEASE]\n");
		gpio_set_value_cansleep(external->led_flash_en, 0);
		break;

	case MSM_CAMERA_LED_OFF:
		cam_err("[MSM_CAMERA_LED_OFF]\n");
#if defined(CONFIG_MACH_CRATER_CHN_CTC) ||  defined(CONFIG_MACH_MELIUS_VZW) || defined(CONFIG_MACH_MELIUS_SPR) || defined(CONFIG_MACH_MELIUS_USC)
		if (system_rev < 0X01) {
#else
		if (system_rev < 0x07) {
#endif
			set_gpio_ENF(external, false);
		} else {
			KTD2692_ctrl_cmd(external, MODE_CONTROL | 0x00);
		}
		break;

	case MSM_CAMERA_LED_LOW:
		/* Movie Current Setting : 0x64 (5/16) */
		cam_err("[MSM_CAMERA_LED_LOW]\n");
#if defined(CONFIG_MACH_CRATER_CHN_CTC) || defined(CONFIG_MACH_MELIUS_VZW) || defined(CONFIG_MACH_MELIUS_SPR) || defined(CONFIG_MACH_MELIUS_USC)
		if (system_rev < 0X01) {
#else
		if (system_rev < 0x07) {
#endif
			for (i = 2; i > 0; i--) {
				set_gpio_ENF(external, false);
				ndelay(300);
				set_gpio_ENF(external, true);
				ndelay(300);
			}
		} else {
			/* Disable Cutoff Low voltage */
			KTD2692_ctrl_cmd(external, LVP_SETTING | 0x00);
			/*KTD2692_ctrl_cmd(external, MOVIE_CURRENT | 0x04);*/
			KTD2692_ctrl_cmd(external, MODE_CONTROL | 0x01);
		}
		break;

	case MSM_CAMERA_LED_HIGH:
		cam_err("[MSM_CAMERA_LED_HIGH]\n");
#if defined(CONFIG_MACH_CRATER_CHN_CTC) || defined(CONFIG_MACH_MELIUS_VZW) || defined(CONFIG_MACH_MELIUS_SPR) || defined(CONFIG_MACH_MELIUS_USC)
		if (system_rev < 0X01) {
#else
		if (system_rev < 0x07) {
#endif
			for (i = 16; i > 0; i--) {
				set_gpio_ENF(external, false);
				ndelay(300);
				set_gpio_ENF(external, true);
				ndelay(300);
			}
		} else {
			/* Disable Cutoff Low voltage */
			KTD2692_ctrl_cmd(external, LVP_SETTING | 0x00);
			/*KTD2692_ctrl_cmd(external, FLASH_CURRENT | 0x0F);*/
			KTD2692_ctrl_cmd(external, MODE_CONTROL | 0x02);
		}
		break;

	default:
		cam_err("[default]\n");
		rc = -EFAULT;
		break;
	}
#elif defined (CONFIG_MACH_SERRANO) || defined (CONFIG_MACH_CRATER) || defined (CONFIG_MACH_BAFFIN)
	/* FLASH IC : MIC2871YMK*/
	cam_err("[led_state::%d]\n", led_state);
	switch (led_state) {
	case MSM_CAMERA_LED_INIT:
		cam_err("[MSM_CAMERA_LED_INIT][MIC2871YMK]\n");
		gpio_tlmm_config(GPIO_CFG(GPIO_MSM_FLASH_CNTL_EN, 0,
			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
			GPIO_CFG_ENABLE);
		gpio_tlmm_config(GPIO_CFG(GPIO_MSM_FLASH_NOW, 0,
			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
			GPIO_CFG_ENABLE);
		break;

	case MSM_CAMERA_LED_RELEASE:
		MIC2871YMK_set_flash_flash(0);
		cam_err("[MSM_CAMERA_LED_RELEASE][MIC2871YMK]\n");
		break;

	case MSM_CAMERA_LED_OFF:
		cam_err("[MSM_CAMERA_LED_OFF][MIC2871YMK]\n");
		MIC2871YMK_set_flash_flash(0);
		break;

	case MSM_CAMERA_LED_LOW:
		cam_err("[MSM_CAMERA_LED_LOW][MIC2871YMK]\n");
		MIC2871YMK_set_flash_movie(1);
		break;

	case MSM_CAMERA_LED_HIGH:
		cam_err("[MSM_CAMERA_LED_HIGH][MIC2871YMK]\n");
		MIC2871YMK_set_flash_flash(1);
		break;

	default:
		cam_err("[default][MIC2871YMK]\n");
		rc = -EFAULT;
		break;
	}
#elif defined (CONFIG_MACH_KS02)
	printk("[led_state::%d]\n", led_state);
	switch (led_state) {
	case MSM_CAMERA_LED_INIT:
		cam_err("[MSM_CAMERA_LED_INIT]\n");
		break;

	case MSM_CAMERA_LED_RELEASE:
		cam_err("[MSM_CAMERA_LED_RELEASE]\n");
		gpio_set_value_cansleep(GPIO_CAM_FLASH_EN, 0);
		gpio_set_value_cansleep(GPIO_CAM_FLASH_SET, 0);
		break;

	case MSM_CAMERA_LED_OFF:
		cam_err("[MSM_CAMERA_LED_OFF]\n");
		gpio_set_value_cansleep(GPIO_CAM_FLASH_EN, 0);
		gpio_set_value_cansleep(GPIO_CAM_FLASH_SET, 0);		
		break;

	case MSM_CAMERA_LED_LOW:
		cam_err("[MSM_CAMERA_LED_LOW]\n");
		gpio_set_value_cansleep(GPIO_CAM_FLASH_SET, 1);
		break;

	case MSM_CAMERA_LED_HIGH:
		cam_err("[MSM_CAMERA_LED_HIGH]\n");
		gpio_set_value_cansleep(GPIO_CAM_FLASH_EN, 1);
		break;

	default:
		cam_err("[default]\n");
		rc = -EFAULT;
		break;
	}
#endif
	return rc;
#elif defined (CONFIG_S5K4ECGX)
#if defined (CONFIG_MACH_CANE)  || defined (CONFIG_MACH_LOGANRE)
	int rc = 0;
	printk("[led_state::%d]\n", led_state);
	switch (led_state) {
	case MSM_CAMERA_LED_INIT:
		cam_err("[MSM_CAMERA_LED_INIT][RT8547]\n");
		gpio_tlmm_config(GPIO_CFG(GPIO_CAM_FLASH_SOURCE_EN, 0,
			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
			GPIO_CFG_ENABLE);
		gpio_tlmm_config(GPIO_CFG(GPIO_CAM_FLASH_SET, 0,
			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
			GPIO_CFG_ENABLE);
		gpio_tlmm_config(GPIO_CFG(GPIO_CAM_FLASH_EN, 0,
			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
			GPIO_CFG_ENABLE);

		/* LVP */
		//RT8547_ctrl_cmd(external, 0x00);
		break;

	case MSM_CAMERA_LED_RELEASE:
		cam_err("[MSM_CAMERA_LED_RELEASE]\n");
		break;

	case MSM_CAMERA_LED_OFF:
		printk("[Torch flash]OFF\n");
#if defined (CONFIG_LEDS_RT8547)
		rt8547_set_led_off();
#endif
		break;

	case MSM_CAMERA_LED_LOW:
		printk("[Torch flash]ON\n");
#if defined (CONFIG_LEDS_RT8547)
		rt8547_set_led_low();
#endif
		break;

	case MSM_CAMERA_LED_HIGH:
		printk("[Torch flash]ON\n");
#if defined (CONFIG_LEDS_RT8547)
		rt8547_set_led_high();
#endif
		break;

	default:
		rc = -EFAULT;
		break;
	}
#endif
	return rc;
#else
	int rc = 0;

	CDBG("msm_camera_flash_led: %d\n", led_state);
	switch (led_state) {
	case MSM_CAMERA_LED_INIT:
		rc = gpio_request(external->led_en, "sgm3141");
		CDBG("MSM_CAMERA_LED_INIT: gpio_req: %d %d\n",
				external->led_en, rc);
		if (!rc)
			gpio_direction_output(external->led_en, 0);
		else
			return 0;

		rc = gpio_request(external->led_flash_en, "sgm3141");
		CDBG("MSM_CAMERA_LED_INIT: gpio_req: %d %d\n",
				external->led_flash_en, rc);
		if (!rc)
			gpio_direction_output(external->led_flash_en, 0);

			break;

	case MSM_CAMERA_LED_RELEASE:
		CDBG("MSM_CAMERA_LED_RELEASE\n");
		gpio_set_value_cansleep(external->led_en, 0);
		gpio_free(external->led_en);
		gpio_set_value_cansleep(external->led_flash_en, 0);
		gpio_free(external->led_flash_en);
		break;

	case MSM_CAMERA_LED_OFF:
		CDBG("MSM_CAMERA_LED_OFF\n");
		gpio_set_value_cansleep(external->led_en, 0);
		gpio_set_value_cansleep(external->led_flash_en, 0);
		break;

	case MSM_CAMERA_LED_LOW:
		CDBG("MSM_CAMERA_LED_LOW\n");
		gpio_set_value_cansleep(external->led_en, 1);
		gpio_set_value_cansleep(external->led_flash_en, 1);
		break;

	case MSM_CAMERA_LED_HIGH:
		CDBG("MSM_CAMERA_LED_HIGH\n");
		gpio_set_value_cansleep(external->led_en, 1);
		gpio_set_value_cansleep(external->led_flash_en, 1);
		break;

	default:
		rc = -EFAULT;
		break;
	}
	return rc;
#endif
}

static void flash_wq_function(struct work_struct *work)
{
	if (tps61310_client) {
		i2c_client.client = tps61310_client;
		i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
		msm_camera_i2c_write(&i2c_client, 0x01,
				0x46, MSM_CAMERA_I2C_BYTE_DATA);
	}
	return;
}

void flash_timer_callback(unsigned long data)
{
	queue_work(flash_wq, (struct work_struct *)work );
	mod_timer(&flash_timer, jiffies + msecs_to_jiffies(10000));
}

int msm_camera_flash_external(
	struct msm_camera_sensor_flash_external *external,
	unsigned led_state)
{
	int rc = 0;

	switch (led_state) {

	case MSM_CAMERA_LED_INIT:
		if (external->flash_id == MAM_CAMERA_EXT_LED_FLASH_SC628A) {
			if (!sc628a_client) {
				rc = i2c_add_driver(&sc628a_i2c_driver);
				if (rc < 0 || sc628a_client == NULL) {
					pr_err("sc628a_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else if (external->flash_id ==
			MAM_CAMERA_EXT_LED_FLASH_TPS61310) {
			if (!tps61310_client) {
				rc = i2c_add_driver(&tps61310_i2c_driver);
				if (rc < 0 || tps61310_client == NULL) {
					pr_err("tps61310_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else {
			pr_err("Flash id not supported\n");
			rc = -ENOTSUPP;
			return rc;
		}

#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && !sx150x_client) {
			struct i2c_adapter *adapter =
			i2c_get_adapter(external->expander_info->bus_id);
			if (adapter)
				sx150x_client = i2c_new_device(adapter,
					external->expander_info->board_info);
			if (!sx150x_client || !adapter) {
				pr_err("sx150x_client is not available\n");
				rc = -ENOTSUPP;
				if (sc628a_client) {
					i2c_del_driver(&sc628a_i2c_driver);
					sc628a_client = NULL;
				}
				if (tps61310_client) {
					i2c_del_driver(&tps61310_i2c_driver);
					tps61310_client = NULL;
				}
				return rc;
			}
			i2c_put_adapter(adapter);
		}
#endif
		if (sc628a_client)
			rc = gpio_request(external->led_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_en, 0);
		} else {
			goto error;
		}

		if (sc628a_client)
			rc = gpio_request(external->led_flash_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_flash_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_flash_en, 0);
			break;
		}

		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
		}
error:
		pr_err("%s gpio request failed\n", __func__);
		if (sc628a_client) {
			i2c_del_driver(&sc628a_i2c_driver);
			sc628a_client = NULL;
		}
		if (tps61310_client) {
			i2c_del_driver(&tps61310_i2c_driver);
			tps61310_client = NULL;
		}
		break;

	case MSM_CAMERA_LED_RELEASE:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
			gpio_set_value_cansleep(external->led_flash_en, 0);
			gpio_free(external->led_flash_en);
			if (sc628a_client) {
				i2c_del_driver(&sc628a_i2c_driver);
				sc628a_client = NULL;
			}
			if (tps61310_client) {
				if (timer_state) {
					del_timer(&flash_timer);
					kfree((void *)work);
					timer_state = 0;
				}
				i2c_del_driver(&tps61310_i2c_driver);
				tps61310_client = NULL;
			}
		}
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && sx150x_client) {
			i2c_unregister_device(sx150x_client);
			sx150x_client = NULL;
		}
#endif
		break;

	case MSM_CAMERA_LED_OFF:
		if (sc628a_client || tps61310_client) {
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
				if (timer_state) {
					del_timer(&flash_timer);
					kfree((void *)work);
					timer_state = 0;
				}
			}
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_set_value_cansleep(external->led_flash_en, 0);
		}
		break;

	case MSM_CAMERA_LED_LOW:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x06, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x46, MSM_CAMERA_I2C_BYTE_DATA);
				flash_wq = create_workqueue("my_queue");
				work = (struct flash_work *)kmalloc(sizeof(struct flash_work), GFP_KERNEL);
				INIT_WORK( (struct work_struct *)work, flash_wq_function );
				setup_timer(&flash_timer, flash_timer_callback, 0);
				mod_timer(&flash_timer, jiffies + msecs_to_jiffies(10000));
				timer_state = 1;
			}
		}
		break;

	case MSM_CAMERA_LED_HIGH:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x49, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x8B, MSM_CAMERA_I2C_BYTE_DATA);
			}
		}
		break;

	default:
		rc = -EFAULT;
		break;
	}
	return rc;
}

static int msm_camera_flash_pwm(
	struct msm_camera_sensor_flash_pwm *pwm,
	unsigned led_state)
{
	int rc = 0;
	int PWM_PERIOD = USEC_PER_SEC / pwm->freq;

	static struct pwm_device *flash_pwm;

	if (!flash_pwm) {
		flash_pwm = pwm_request(pwm->channel, "camera-flash");
		if (flash_pwm == NULL || IS_ERR(flash_pwm)) {
			pr_err("%s: FAIL pwm_request(): flash_pwm=%p\n",
			       __func__, flash_pwm);
			flash_pwm = NULL;
			return -ENXIO;
		}
	}

	switch (led_state) {
	case MSM_CAMERA_LED_LOW:
		rc = pwm_config(flash_pwm,
			(PWM_PERIOD/pwm->max_load)*pwm->low_load,
			PWM_PERIOD);
		if (rc >= 0)
			rc = pwm_enable(flash_pwm);
		break;

	case MSM_CAMERA_LED_HIGH:
		rc = pwm_config(flash_pwm,
			(PWM_PERIOD/pwm->max_load)*pwm->high_load,
			PWM_PERIOD);
		if (rc >= 0)
			rc = pwm_enable(flash_pwm);
		break;

	case MSM_CAMERA_LED_OFF:
		pwm_disable(flash_pwm);
		break;
	case MSM_CAMERA_LED_INIT:
	case MSM_CAMERA_LED_RELEASE:
		break;

	default:
		rc = -EFAULT;
		break;
	}
	return rc;
}

int msm_camera_flash_pmic(
	struct msm_camera_sensor_flash_pmic *pmic,
	unsigned led_state)
{
	int rc = 0;

	switch (led_state) {
	case MSM_CAMERA_LED_OFF:
		rc = pmic->pmic_set_current(pmic->led_src_1, 0);
		if (pmic->num_of_src > 1)
			rc = pmic->pmic_set_current(pmic->led_src_2, 0);
		break;

	case MSM_CAMERA_LED_LOW:
		rc = pmic->pmic_set_current(pmic->led_src_1,
				pmic->low_current);
		if (pmic->num_of_src > 1)
			rc = pmic->pmic_set_current(pmic->led_src_2, 0);
		break;

	case MSM_CAMERA_LED_HIGH:
		rc = pmic->pmic_set_current(pmic->led_src_1,
			pmic->high_current);
		if (pmic->num_of_src > 1)
			rc = pmic->pmic_set_current(pmic->led_src_2,
				pmic->high_current);
		break;

	case MSM_CAMERA_LED_INIT:
	case MSM_CAMERA_LED_RELEASE:
		 break;

	default:
		rc = -EFAULT;
		break;
	}
	CDBG("flash_set_led_state: return %d\n", rc);

	return rc;
}
Ejemplo n.º 3
0
static int marimba_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct marimba_platform_data *pdata = client->dev.platform_data;
	struct i2c_adapter *ssbi_adap;
	struct marimba *marimba;
	int i, status, rc, client_loop, adie_slave_idx_offset;
	int rc_bahama = 0, rc_marimba = 0;

	if (!pdata) {
		dev_dbg(&client->dev, "no platform data?\n");
		return -EINVAL;
	}

	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
		dev_dbg(&client->dev, "can't talk I2C?\n");
		return -EIO;
	}

	/* First, identify the codec type */
	if (pdata->marimba_setup != NULL) {
		rc_marimba = pdata->marimba_setup();
		if (rc_marimba)
			pdata->marimba_shutdown();
	}

	if (pdata->bahama_setup != NULL &&
		cur_connv_type != BAHAMA_ID) {
		rc_bahama = pdata->bahama_setup();
		if (rc_bahama)
			pdata->bahama_shutdown(cur_connv_type);
	}

	if (rc_marimba & rc_bahama)
		return -EAGAIN;

	marimba = &marimba_modules[ADIE_ARRY_SIZE - 1];
	marimba->client = client;
	mutex_init(&marimba->xfer_lock);

	rc = get_adie_type();

	mutex_destroy(&marimba->xfer_lock);

	if (rc < 0) {
		if (pdata->bahama_setup != NULL)
			pdata->bahama_shutdown(cur_adie_type);
		if (pdata->marimba_shutdown != NULL)
			pdata->marimba_shutdown();
		return 0;
	}

	if (rc < 2) {
		adie_arry_idx = 0;
		adie_slave_idx_offset = 0;
		client_loop = 0;
		cur_codec_type = rc;
		if (cur_connv_type < 0)
			cur_connv_type = rc;
		if (pdata->bahama_shutdown != NULL)
			pdata->bahama_shutdown(cur_connv_type);
	} else {
		adie_arry_idx = 5;
		adie_slave_idx_offset = 5;
		client_loop = 1;
		cur_connv_type = rc;
	}

	marimba = &marimba_modules[adie_arry_idx];
	marimba->client = client;
	mutex_init(&marimba->xfer_lock);

	for (i = 1; i <= (NUM_ADD - client_loop); i++) {
		/* Skip adding BT/FM for Timpani */
		if (i == 1 && rc >= 1)
			i++;
		marimba = &marimba_modules[i + adie_arry_idx];
		if (i != MARIMBA_ID_TSADC)
			marimba->client = i2c_new_dummy(client->adapter,
				pdata->slave_id[i + adie_slave_idx_offset]);
		else {
			ssbi_adap = i2c_get_adapter(MARIMBA_SSBI_ADAP);
			marimba->client = i2c_new_dummy(ssbi_adap,
						0x55);
		}
		if (!marimba->client) {
			dev_err(&marimba->client->dev,
				"can't attach client %d\n", i);
			status = -ENOMEM;
			goto fail;
		}
		strlcpy(marimba->client->name, id->name,
			sizeof(marimba->client->name));

		mutex_init(&marimba->xfer_lock);
	}

	marimba_init_reg(client, id->driver_data);

	status = marimba_add_child(pdata, id->driver_data);

	marimba_pdata = pdata;

	return 0;

fail:
	return status;
}
Ejemplo n.º 4
0
/*
 * Assign v4l2 device and subdev to fimc
 * it is called per every fimc ctrl registering
 */
static int fimc_configure_subdev(struct platform_device *pdev, int id)
{
	struct s3c_platform_fimc *pdata;
	struct s3c_platform_camera *cam;
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info *i2c_info;
	struct v4l2_subdev *sd;
	struct fimc_control *ctrl;
	unsigned short addr;
	char *name;

	ctrl = get_fimc_ctrl(id);
	pdata = to_fimc_plat(&pdev->dev);
	cam = pdata->camera[id];

	/* Subdev registration */
	if (cam) {
		i2c_adap = i2c_get_adapter(cam->i2c_busnum);
		if (!i2c_adap) {
			fimc_info1("subdev i2c_adapter missing-skip "
							"registration\n");
		}

		i2c_info = cam->info;
		if (!i2c_info) {
			fimc_err("%s: subdev i2c board info missing\n",
								__func__);
			return -ENODEV;
		}

		name = i2c_info->type;
		if (!name) {
			fimc_info1("subdev i2c dirver name missing-skip "
				"registration\n");
			return -ENODEV;
		}

		addr = i2c_info->addr;
		if (!addr) {
			fimc_info1("subdev i2c address missing-skip "
							"registration\n");
			return -ENODEV;
		}

		/*
		 * NOTE: first time subdev being registered,
		 * s_config is called and try to initialize subdev device
		 * but in this point, we are not giving MCLK and power to subdev
		 * so nothing happens but pass platform data through
		 */
		sd = v4l2_i2c_new_subdev_board(&ctrl->v4l2_dev, i2c_adap,
				name, i2c_info, &addr);
		if (!sd) {
			fimc_err("%s: v4l2 subdev board registering failed\n",
				__func__);
		}

		/* Assign camera device to fimc */
		fimc_dev->camera[cam->id] = cam;

		/* Assign subdev to proper camera device pointer */
		fimc_dev->camera[cam->id]->sd = sd;
	}

	return 0;
}
Ejemplo n.º 5
0
int check_boxtype(void)
{
    int ret;
    unsigned char buf;
//    b[] = { 0x01, 0xff };
//    struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = b, .len = 2 };

    struct i2c_msg msg = {.addr = 0x08, I2C_M_RD, .buf = &buf, .len = 1 };

    struct i2c_adapter *i2c_adap = i2c_get_adapter (I2C_BUS);
    ret=i2c_transfer(i2c_adap, &msg, 1);
    return ret;
}

/************************************************************************
*
* Unfortunately there is no generic mechanism to unambiguously determine
* STBs from different manufactureres. Since each hardware platform needs
* special I/O pin handling it also requires a different kernel image.
* Setting platform device configuration in the kernel helps to roughly
* determine the STB type. Further identification can be based on reading
* an EPLD or I/O pins.
* To provide a platform identification data add a platform device
* to the board setup.c file as follows:
*
*   static struct platform_device boxtype_device = {
*        .name = "boxtype",
*        .dev.platform_data = (void*)NEW_ID
*   };
*
*   static struct platform_device *plat_devices[] __initdata = {
*           &boxtype_device,
*           &st40_ohci_devices,
*           &st40_ehci_devices,
*           &ssc_device,
*   ...
*
* Where NEW_ID is a unique integer identifying the platform and
* plat_devices is provided to the platform_add_devices() function
* during initialization of hardware resources.
*
************************************************************************/
static int boxtype_probe (struct device *dev)
{
  struct platform_device *pdev = to_platform_device (dev);

  if(pdev != NULL)
    boxtype = (int)pdev->dev.platform_data;

  return 0;
}

static int boxtype_remove (struct device *dev)
{
  return 0;
}

static struct device_driver boxtype_driver = {
  .name = DEVICENAME,
  .bus = &platform_bus_type,
  .owner = THIS_MODULE,
  .probe = boxtype_probe,
  .remove = boxtype_remove,
};

int procfile_read(char *buffer, char **buffer_location,
	          off_t offset, int buffer_length, int *eof, void *data)
{
	int ret;

	if (offset > 0) {
		ret  = 0;
	} else {
		if (boxtype==ESI88) ret = sprintf(buffer, "ESI88\n");
		else
		if (boxtype==UHD88) ret = sprintf(buffer, "UHD88\n");
		else
		ret = sprintf(buffer, "UNKNOWN\n");
	}
	return ret;
}
Ejemplo n.º 6
0
/*
** Called at initialization time.
*/
IMMVIBESPIAPI VibeStatus ImmVibeSPI_ForceOut_Initialize(void)
{
    struct i2c_adapter* adapter;
    struct i2c_client* client;
    int retVal = 0;

    DbgOut((DBL_VERBOSE, "ImmVibeSPI_ForceOut_Initialize.\n"));

    g_bAmpEnabled = true;	/* to force ImmVibeSPI_ForceOut_AmpDisable disabling the amp */

    /* From Xiaomi start*/
    vibe_strength = REAL_TIME_PLAYBACK_CALIBRATION_STRENGTH;
    if (get_hw_version_major() == 5)
        GPIO_VIBTONE_EN1 = 64;
    else
        GPIO_VIBTONE_EN1 = 86;

    if (gpio_request(GPIO_VIBTONE_EN1, "vibrator-en") < 0) {
        printk(KERN_ALERT"drv2604: error requesting gpio\n");
        return VIBE_E_FAIL;
    }
    /* From Xiaomi end */

    adapter = i2c_get_adapter(DEVICE_BUS);

    if (adapter) {
        client = i2c_new_device(adapter, &info);

        if (client) {
            retVal = i2c_add_driver(&drv2604_driver);

            if (retVal)
                return VIBE_E_FAIL;
        } else {
            DbgOut((DBL_VERBOSE, "drv2604: Cannot create new device.\n"));
            return VIBE_E_FAIL;
        }
    } else {
        DbgOut((DBL_VERBOSE, "ImmVibeSPI_ForceOut_AmpDisable.\n"));
        return VIBE_E_FAIL;
    }

    if(g_autotune_brake_enabled)
        g_workqueue = create_workqueue("tspdrv_workqueue");

    /* From Xiaomi start */
    if (timed_output_dev_register(&to_dev) < 0) {
        printk(KERN_ALERT"drv2604: fail to create timed output dev: enable\n");
        gpio_direction_output(GPIO_VIBTONE_EN1, GPIO_LEVEL_LOW);
        gpio_free(GPIO_VIBTONE_EN1);
        i2c_del_driver(&drv2604_driver);
        i2c_unregister_device(client);
        return VIBE_E_FAIL;
    }

    if ( device_create_bin_file(to_dev.dev, &drv2604_bin_attrs)) {
        printk(KERN_ALERT"drv2604: fail to create timed output dev: pattern\n");
        return VIBE_E_FAIL;
    }

    hrtimer_init(&vibdata.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    vibdata.timer.function = vibrator_timer_func;
    INIT_WORK(&vibdata.work, vibrator_work);
    // INIT_WORK(&vibdata.work_play_eff, play_effect);

    wake_lock_init(&vibdata.wklock, WAKE_LOCK_SUSPEND, "vibrator");
    mutex_init(&vibdata.lock);

    /* PWM */
    /*
    vibdata.pwm_dev = pwm_request(PWM_CH_ID, "drv2604");
    if (IS_ERR(vibdata.pwm_dev))
    	dev_err(&client->dev, "%s: pwm request failed\n", __func__);
    */
    printk(KERN_ALERT"drv2604: initialized on M3\n");
    /* From Xiaomi end */

    ImmVibeSPI_ForceOut_AmpDisable(0);

    vibe_kobj = kobject_create_and_add("vibrator", NULL);
    if (!vibe_kobj)
        return VIBE_S_SUCCESS;

    retVal = sysfs_create_file(vibe_kobj, &dev_attr_pwmvalue.attr);

    if (retVal)
        DbgOut((DBL_VERBOSE, "drv2604: vibrator creat fail.\n"));

    return VIBE_S_SUCCESS;
}
Ejemplo n.º 7
0
static int atomisp_subdev_probe(struct atomisp_device *isp)
{
	const struct atomisp_platform_data *pdata;
	struct intel_v4l2_subdev_table *subdevs;
	int raw_index = -1;

	pdata = atomisp_get_platform_data();
	if (pdata == NULL) {
		dev_err(isp->dev, "no platform data available\n");
		return 0;
	}

	for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) {
		struct v4l2_subdev *subdev;
		struct i2c_board_info *board_info =
			&subdevs->v4l2_subdev.board_info;
		struct i2c_adapter *adapter =
			i2c_get_adapter(subdevs->v4l2_subdev.i2c_adapter_id);

		if (adapter == NULL) {
			dev_err(isp->dev,
				"Failed to find i2c adapter for subdev %s\n",
				board_info->type);
			break;
		}

		subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
				board_info, NULL);

		if (subdev == NULL) {
			dev_warn(isp->dev, "Subdev %s detection fail\n",
				 board_info->type);
			continue;
		}

		dev_info(isp->dev, "Subdev %s successfully register\n",
			 board_info->type);

		switch (subdevs->type) {
		case RAW_CAMERA:
			raw_index = isp->input_cnt;
			dev_dbg(isp->dev, "raw_index: %d\n", raw_index);
		case SOC_CAMERA:
			dev_dbg(isp->dev, "SOC_INDEX: %d\n", isp->input_cnt);
			if (isp->input_cnt >= ATOM_ISP_MAX_INPUTS) {
				dev_warn(isp->dev,
					 "too many atomisp inputs, ignored\n");
				break;
			}

			isp->inputs[isp->input_cnt].type = subdevs->type;
			isp->inputs[isp->input_cnt].port = subdevs->port;
			isp->inputs[isp->input_cnt].camera = subdev;
			isp->inputs[isp->input_cnt].shading_table = NULL;
			isp->inputs[isp->input_cnt].morph_table = NULL;
			/*
			 * initialize the subdev frame size, then next we can
			 * judge whether frame_size store effective value via
			 * pixel_format.
			 */
			isp->inputs[isp->input_cnt].frame_size.pixel_format = 0;
			isp->input_cnt++;
			break;
		case CAMERA_MOTOR:
			isp->motor = subdev;
			break;
		case LED_FLASH:
		case XENON_FLASH:
			isp->flash = subdev;
			break;
		default:
			dev_dbg(isp->dev, "unknown subdev probed\n");
			break;
		}

	}

	/*
	 * HACK: Currently VCM belongs to primary sensor only, but correct
	 * approach must be to acquire from platform code which sensor
	 * owns it.
	 */
	if (isp->motor && raw_index >= 0)
		isp->inputs[raw_index].motor = isp->motor;

	/* Proceed even if no modules detected. For COS mode and no modules. */
	if (!isp->inputs[0].camera)
		dev_warn(isp->dev, "no camera attached or fail to detect\n");

	if (IS_ISP2400)
		return mrfld_csi_lane_config(isp);

	return 0;
}
Ejemplo n.º 8
0
static int omapbmi_slot_probe(struct platform_device *pdev)
{
  struct bmi_slot *slot;
  struct resource *irq_pres, *irq_stat;
  struct omap_bmi_platform_data* slot_pdata;
  int ret;

  
  printk(KERN_INFO "Buglabs 2.0 BUG Slots Driver...\n"); 
  irq_pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  if (!irq_pres) {
    dev_err(&pdev->dev, "No presence irq resource...\n");
    return -ENODEV;
  }
  irq_stat = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
  if (!irq_stat) {
    dev_err(&pdev->dev, "No status irq resource...\n");
    return -ENODEV;
  }

  slot = kzalloc(sizeof(struct bmi_slot), GFP_KERNEL);
  if (!slot) {
    ret = -ENOMEM;
    goto err_release;
  }
  
  //Request slot enable gpios
  ret = gpio_request(225, "slot0 buf");
  ret = gpio_request(226, "slot0 en");
  ret = gpio_request(232, "slot1 buf");
  ret = gpio_request(227, "slot1 en");
  ret = gpio_request(216, "slot2 buf");
  ret = gpio_request(228, "slot2 en");
  ret = gpio_request(217, "slot3 buf");
  ret = gpio_request(229, "slot3 en");
  ret = gpio_request(irq_stat->start, "BMI SINT");
  if (ret) {
    printk(KERN_ERR "slots_bug: GPIO %d request failed...\n",irq_stat->start);
    goto err_release;
  }
  ret = gpio_request(irq_pres->start, "BMI PINT");
  if (ret) {
    printk(KERN_ERR "slots_bug: GPIO %d request failed...\n",irq_pres->start);
    goto err_release;
  }
  
  ret = gpio_direction_input(irq_pres->start);
  omap_set_gpio_debounce(irq_pres->start, 1);
  omap_set_gpio_debounce_time(irq_pres->start, 0xff);
  slot_pdata = pdev->dev.platform_data;

  omapbmi_slot_gpio_req(slot_pdata->gpios);
  
  
  slot->slot_data = (void*)slot_pdata->gpios;
  slot->present_irq = gpio_to_irq(irq_pres->start);
  slot->status_irq = gpio_to_irq(irq_stat->start);
  slot->owner = THIS_MODULE;
  slot->name = "omap_bug_slot";
  slot->slotdev.parent = &pdev->dev;
  slot->adap = i2c_get_adapter(slot_pdata->i2c_bus_no);
  slot->actions = &bl_actions;
  slot->spi_bus_num = 1;
  slot->spi_cs = slot_pdata->spi_cs;
  
  
  ret = bmi_add_slot(slot);
  if (ret) {
    printk(KERN_ERR "slots_bug: Trouble instantiating slot...%d\n", ret);
    goto err_release;
  }
  
  //  disable_irq_nosync(slot->present_irq);
  schedule_delayed_work(&slot->work, msecs_to_jiffies(1000));
  return 0;
 err_release:
  kfree(slot->slot_data);
  kfree(slot);
  return ret;
}
Ejemplo n.º 9
0
static int __devinit gpiomux_probe(struct platform_device *pdev)
{
	struct gpiomux *mux;
	struct gpio_i2cmux_platform_data *pdata;
	struct i2c_adapter *parent;
	int (*deselect) (struct i2c_adapter *, void *, u32);
	unsigned initial_state;
	int i, ret;

	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev, "Missing platform data\n");
		return -ENODEV;
	}

	parent = i2c_get_adapter(pdata->parent);
	if (!parent) {
		dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
			pdata->parent);
		return -ENODEV;
	}

	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
	if (!mux) {
		ret = -ENOMEM;
		goto alloc_failed;
	}

	mux->parent = parent;
	mux->data = *pdata;
	mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values,
			    GFP_KERNEL);
	if (!mux->adap) {
		ret = -ENOMEM;
		goto alloc_failed2;
	}

	if (pdata->idle != GPIO_I2CMUX_NO_IDLE) {
		initial_state = pdata->idle;
		deselect = gpiomux_deselect;
	} else {
		initial_state = pdata->values[0];
		deselect = NULL;
	}

	for (i = 0; i < pdata->n_gpios; i++) {
		ret = gpio_request(pdata->gpios[i], "gpio-i2cmux");
		if (ret)
			goto err_request_gpio;
		gpio_direction_output(pdata->gpios[i],
				      initial_state & (1 << i));
	}

	for (i = 0; i < pdata->n_values; i++) {
		u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;

		mux->adap[i] = i2c_add_mux_adapter(parent, mux, nr, i,
						   gpiomux_select, deselect);
		if (!mux->adap[i]) {
			ret = -ENODEV;
			dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
			goto add_adapter_failed;
		}
	}

	dev_info(&pdev->dev, "%d port mux on %s adapter\n",
		 pdata->n_values, parent->name);

	platform_set_drvdata(pdev, mux);

	return 0;

add_adapter_failed:
	for (; i > 0; i--)
		i2c_del_mux_adapter(mux->adap[i - 1]);
	i = pdata->n_gpios;
err_request_gpio:
	for (; i > 0; i--)
		gpio_free(pdata->gpios[i - 1]);
	kfree(mux->adap);
alloc_failed2:
	kfree(mux);
alloc_failed:
	i2c_put_adapter(parent);

	return ret;
}
Ejemplo n.º 10
0
static int hdmi_i2c_write_data(struct i2c_adapter * adapter, unsigned char adr, unsigned char *data, int size)
{
        struct i2c_msg msg = {
                .addr = adr,.flags = 0,.buf = data,.len = size
        };
        return i2c_transfer(adapter, &msg, 1);
}

static struct i2c_adapter * hdmi_i2c_get_adapter(struct i2c_client *c)
{
        /* For HDMI if not plugged in, then i2c core may not create the client driver */
        /* Should use the adapter directly */
        if(c)
	   return c->adapter;
	else
	   return i2c_get_adapter(MDFLD_HDMI_I2C_ADAPTER_ID);
} 

static struct mdfld_hdmi_i2c hdmi_i2c_bus = {
	.open = hdmi_i2c_open,
	.close = hdmi_i2c_close,
	.read_byte_data = hdmi_i2c_read_byte_data,
	.write_byte_data = hdmi_i2c_write_byte_data,
	.read_data = hdmi_i2c_read_data,
	.write_data = hdmi_i2c_write_data,
	.get_adapter = hdmi_i2c_get_adapter,
};

struct mdfld_hdmi_i2c * hdmi_i2c_init()
{
	return &hdmi_i2c_bus;
}

/*
 *  * i2c addresses to scan 
 *  0x28 is from 0x50 >> 1 to remove first bit for ddc address 
 *  0x39 is from 0x73 >> 1 for HDCP address
 *   */
static unsigned short normal_i2c[] = {0x28, 0x39, I2C_CLIENT_END};
I2C_CLIENT_INSMOD;

/* Each client has this additional data */
struct mdfld_hdmi_i2c_data {
	struct semaphore data_lock;
	int data;
};

static const struct i2c_device_id mdfld_hdmi_id[] = {
	{"mdfld_hdmi", 0},
	{}
};

static int mdfld_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	return 0;
}

/* This function is called by i2c_detect */
static int mdfld_detect(struct i2c_client *client, int kind,
			 struct i2c_board_info *info)
{
	struct i2c_adapter *adapter = client->adapter;
	struct mdfld_hdmi_i2c_data *data = NULL;
	int err = 0;

	/* HDMI i2c is i2c3 with id = 3 */
	if (adapter->id !=3) {
		err = -ENODEV;
		goto error;
	}
		
	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
		err = -ENODEV;
		goto error;
	}

	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto error;
	}
			
	memset(data, 0x00, sizeof(*data));
	
	i2c_set_clientdata(client, data);
	
	if (client->addr == 0xA0)
		hdmi_i2c_bus.ddc_client = client;
	else	
		hdmi_i2c_bus.hdcp_client = client;		

	return 0;

error:
	if(data != NULL) kfree(data);
	return err;
}

static int mdfld_remove(struct i2c_client *client)
{
	struct mdfld_hdmi_i2c_data *data = i2c_get_clientdata(client);
	kfree(data);
	return 0;
}

/* This is the driver that will be inserted */
static struct i2c_driver mdfld_hdmi_i2c_driver = {
	.driver = {
		.name		= "mdfld_hdmi",
	},
	.probe = mdfld_probe,
	.remove = mdfld_remove,
	.id_table = mdfld_hdmi_id,

	.class = I2C_CLASS_DDC,
	.detect = mdfld_detect,
	.address_data = &addr_data,
};


static int __init mdfld_i2c_init(void)
{
        hdmi_i2c_bus.ddc_client = NULL;
        hdmi_i2c_bus.hdcp_client = NULL;
        
	return i2c_add_driver(&mdfld_hdmi_i2c_driver);
}
Ejemplo n.º 11
0
/**
 * vpbe_initialize() - Initialize the vpbe display controller
 * @vpbe_dev - vpbe device ptr
 *
 * Master frame buffer device drivers calls this to initialize vpbe
 * display controller. This will then registers v4l2 device and the sub
 * devices and sets a current encoder sub device for display. v4l2 display
 * device driver is the master and frame buffer display device driver is
 * the slave. Frame buffer display driver checks the initialized during
 * probe and exit if not initialized. Returns status.
 */
static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
{
	struct encoder_config_info *enc_info;
	struct amp_config_info *amp_info;
	struct v4l2_subdev **enc_subdev;
	struct osd_state *osd_device;
	struct i2c_adapter *i2c_adap;
	int output_index;
	int num_encoders;
	int ret = 0;
	int err;
	int i;

	/*
	 * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
	 * from the platform device by iteration of platform drivers and
	 * matching with device name
	 */
	if (NULL == vpbe_dev || NULL == dev) {
		printk(KERN_ERR "Null device pointers.\n");
		return -ENODEV;
	}

	if (vpbe_dev->initialized)
		return 0;

	mutex_lock(&vpbe_dev->lock);

	if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
		/* We have dac clock available for platform */
		vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
		if (IS_ERR(vpbe_dev->dac_clk)) {
			ret =  PTR_ERR(vpbe_dev->dac_clk);
			goto fail_mutex_unlock;
		}
		if (clk_prepare_enable(vpbe_dev->dac_clk)) {
			ret =  -ENODEV;
			goto fail_mutex_unlock;
		}
	}

	/* first enable vpss clocks */
	vpss_enable_clock(VPSS_VPBE_CLOCK, 1);

	/* First register a v4l2 device */
	ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
	if (ret) {
		v4l2_err(dev->driver,
			"Unable to register v4l2 device.\n");
		goto fail_clk_put;
	}
	v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");

	err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
			       platform_device_get);
	if (err < 0)
		return err;

	vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
					   vpbe_dev->cfg->venc.module_name);
	/* register venc sub device */
	if (vpbe_dev->venc == NULL) {
		v4l2_err(&vpbe_dev->v4l2_dev,
			"vpbe unable to init venc sub device\n");
		ret = -ENODEV;
		goto fail_dev_unregister;
	}
	/* initialize osd device */
	osd_device = vpbe_dev->osd_device;

	if (NULL != osd_device->ops.initialize) {
		err = osd_device->ops.initialize(osd_device);
		if (err) {
			v4l2_err(&vpbe_dev->v4l2_dev,
				 "unable to initialize the OSD device");
			err = -ENOMEM;
			goto fail_dev_unregister;
		}
	}

	/*
	 * Register any external encoders that are configured. At index 0 we
	 * store venc sd index.
	 */
	num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
	vpbe_dev->encoders = kmalloc(
				sizeof(struct v4l2_subdev *)*num_encoders,
				GFP_KERNEL);
	if (NULL == vpbe_dev->encoders) {
		v4l2_err(&vpbe_dev->v4l2_dev,
			"unable to allocate memory for encoders sub devices");
		ret = -ENOMEM;
		goto fail_dev_unregister;
	}

	i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
	for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
		if (i == 0) {
			/* venc is at index 0 */
			enc_subdev = &vpbe_dev->encoders[i];
			*enc_subdev = vpbe_dev->venc;
			continue;
		}
		enc_info = &vpbe_dev->cfg->ext_encoders[i];
		if (enc_info->is_i2c) {
			enc_subdev = &vpbe_dev->encoders[i];
			*enc_subdev = v4l2_i2c_new_subdev_board(
						&vpbe_dev->v4l2_dev, i2c_adap,
						&enc_info->board_info, NULL);
			if (*enc_subdev)
				v4l2_info(&vpbe_dev->v4l2_dev,
					  "v4l2 sub device %s registered\n",
					  enc_info->module_name);
			else {
				v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s"
					 " failed to register",
					 enc_info->module_name);
				ret = -ENODEV;
				goto fail_kfree_encoders;
			}
		} else
			v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
				 " currently not supported");
	}
	/* Add amplifier subdevice for dm365 */
	if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
			vpbe_dev->cfg->amp != NULL) {
		amp_info = vpbe_dev->cfg->amp;
		if (amp_info->is_i2c) {
			vpbe_dev->amp = v4l2_i2c_new_subdev_board(
			&vpbe_dev->v4l2_dev, i2c_adap,
			&amp_info->board_info, NULL);
			if (!vpbe_dev->amp) {
				v4l2_err(&vpbe_dev->v4l2_dev,
					 "amplifier %s failed to register",
					 amp_info->module_name);
				ret = -ENODEV;
				goto fail_kfree_encoders;
			}
			v4l2_info(&vpbe_dev->v4l2_dev,
					  "v4l2 sub device %s registered\n",
					  amp_info->module_name);
		} else {
			    vpbe_dev->amp = NULL;
			    v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers"
			    " currently not supported");
		}
	} else {
	    vpbe_dev->amp = NULL;
	}

	/* set the current encoder and output to that of venc by default */
	vpbe_dev->current_sd_index = 0;
	vpbe_dev->current_out_index = 0;
	output_index = 0;

	mutex_unlock(&vpbe_dev->lock);

	printk(KERN_NOTICE "Setting default output to %s\n", def_output);
	ret = vpbe_set_default_output(vpbe_dev);
	if (ret) {
		v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
			 def_output);
		return ret;
	}

	printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
	ret = vpbe_set_default_mode(vpbe_dev);
	if (ret) {
		v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
			 def_mode);
		return ret;
	}
	vpbe_dev->initialized = 1;
	/* TBD handling of bootargs for default output and mode */
	return 0;

fail_kfree_encoders:
	kfree(vpbe_dev->encoders);
fail_dev_unregister:
	v4l2_device_unregister(&vpbe_dev->v4l2_dev);
fail_clk_put:
	if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
		clk_disable_unprepare(vpbe_dev->dac_clk);
		clk_put(vpbe_dev->dac_clk);
	}
fail_mutex_unlock:
	mutex_unlock(&vpbe_dev->lock);
	return ret;
}
Ejemplo n.º 12
0
static int __init i2clcd857_init(void)
{
    int ret;
    struct i2c_board_info board_info = {
                    .type = "lcdi2c",
                    .addr = address,

    };

    adapter = i2c_get_adapter(busno);
    if (!adapter) return -EINVAL;

     client = i2c_new_device(adapter, &board_info);
     if (!client) return -EINVAL;

    ret = i2c_add_driver(&lcdi2c_driver);
    if (ret)
    {
        i2c_put_adapter(adapter);
        return ret;
    }

    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
    {
        i2c_put_adapter(adapter);
        dev_err(&client->dev, "no algorithms associated to i2c bus\n");
        return -ENODEV;
    }

    i2c_put_adapter(adapter);

    major = register_chrdev(major, DEVICE_NAME, &lcdi2c_fops);
    if (major < 0)
    {
        dev_warn(&client->dev, "failed to register device with error: %d\n",
		 major);
        goto failed_chrdev;
    }

    lcdi2c_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME);
    if (IS_ERR(lcdi2c_class))
    {
        dev_warn(&client->dev, "class creation failed %s\n", DEVICE_CLASS_NAME);
        goto failed_class;
    }

    lcdi2c_device = device_create(lcdi2c_class, NULL, MKDEV(major, minor), NULL,
				  DEVICE_NAME);
    if (IS_ERR(lcdi2c_device))
    {
        dev_warn(&client->dev, "device %s creation failed\n", DEVICE_NAME);
        goto failed_device;
    }

    if(sysfs_create_group(&lcdi2c_device->kobj, &i2clcd_device_attr_group))
    {
        dev_warn(&client->dev, "device attribute group creation failed\n");
        goto failed_device;
    }

     dev_info(&client->dev, "registered with major %u\n", major);


    return ret;

    failed_device:
        class_unregister(lcdi2c_class);
        class_destroy(lcdi2c_class);
    failed_class:
        unregister_chrdev(major, DEVICE_NAME);
    failed_chrdev:
        i2c_unregister_device(client);
        i2c_del_driver(&lcdi2c_driver);
    return -1;
}


static void __exit i2clcd857_exit(void)
{

    unregister_chrdev(major, DEVICE_NAME);

    sysfs_remove_group(&lcdi2c_device->kobj, &i2clcd_device_attr_group);
    device_destroy(lcdi2c_class, MKDEV(major, 0));
    class_unregister(lcdi2c_class);
    class_destroy(lcdi2c_class);
    unregister_chrdev(major, DEVICE_NAME);

     if (client)
         i2c_unregister_device(client);

    i2c_del_driver(&lcdi2c_driver);
}
Ejemplo n.º 13
0
static int __devinit hdmi_probe(struct platform_device *pdev)
{
	struct s5p_hdmi_platdata *pdata;
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct i2c_adapter *phy_adapter;
	struct hdmi_device *hdmi_dev = NULL;
	struct hdmi_driver_data *drv_data;
	int ret;

	dev_dbg(dev, "probe start\n");

	hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL);
	if (!hdmi_dev) {
		dev_err(dev, "out of memory\n");
		ret = -ENOMEM;
		goto fail;
	}

	hdmi_dev->dev = dev;

	ret = hdmi_resources_init(hdmi_dev);
	if (ret)
		goto fail_hdev;

	/* mapping HDMI registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "get hdmi memory resource failed.\n");
		ret = -ENXIO;
		goto fail_init;
	}

	hdmi_dev->regs = ioremap(res->start, resource_size(res));
	if (hdmi_dev->regs == NULL) {
		dev_err(dev, "hdmi register mapping failed.\n");
		ret = -ENXIO;
		goto fail_hdev;
	}

	/* mapping HDMIPHY_APB registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res == NULL) {
		dev_err(dev, "get hdmiphy memory resource failed.\n");
		ret = -ENXIO;
		goto fail_init;
	}

	hdmi_dev->phy_regs = ioremap(res->start, resource_size(res));
	if (hdmi_dev->phy_regs == NULL) {
		dev_err(dev, "hdmiphy register mapping failed.\n");
		ret = -ENXIO;
		goto fail_hdev;
	}

	/* External hpd */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		dev_err(dev, "get external interrupt resource failed.\n");
		ret = -ENXIO;
		goto fail_regs;
	}
	hdmi_dev->ext_irq = res->start;

	/* Internal hpd */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (res == NULL) {
		dev_err(dev, "get internal interrupt resource failed.\n");
		ret = -ENXIO;
		goto fail_regs;
	}
	hdmi_dev->int_irq = res->start;

	INIT_WORK(&hdmi_dev->hpd_work, hdmi_hpd_work);
	INIT_DELAYED_WORK(&hdmi_dev->hdmi_probe_work, hdmiphy_poweroff_work);
	INIT_DELAYED_WORK(&hdmi_dev->hpd_work_ext, hdmi_hpd_work_ext);
	mutex_init(&hdmi_dev->mutex);

	/* setting v4l2 name to prevent WARN_ON in v4l2_device_register */
	strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev),
		sizeof(hdmi_dev->v4l2_dev.name));
	/* passing NULL owner prevents driver from erasing drvdata */
	ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev);
	if (ret) {
		dev_err(dev, "could not register v4l2 device.\n");
		goto fail_lock;
	}

	pdata = pdev->dev.platform_data;
	dev_info(dev, "hdmi ip version = %d\n", pdata->ip_ver);

	/* store hdmi platform data to hdmi context */
	hdmi_dev->pdata = pdata;

	if (soc_is_exynos5250()) {
		drv_data = (struct hdmi_driver_data *)
			platform_get_device_id(pdev)->driver_data;
		dev_info(dev, "hdmiphy i2c bus number = %d\n", drv_data->hdmiphy_bus);

		phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus);
		if (phy_adapter == NULL) {
			dev_err(dev, "adapter request failed\n");
			ret = -ENXIO;
			goto fail_vdev;
		}

		hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev,
				phy_adapter, &hdmiphy_info, NULL);
		/* on failure or not adapter is no longer useful */
		i2c_put_adapter(phy_adapter);
		if (hdmi_dev->phy_sd == NULL) {
			dev_err(dev, "missing subdev for hdmiphy\n");
			ret = -ENODEV;
			goto fail_vdev;
		}
	}

	hdmi_dev->hpd_switch.name = "hdmi";
	ret = switch_dev_register(&hdmi_dev->hpd_switch);
	if (ret) {
		dev_err(dev, "request switch class failed.\n");
		goto fail_vdev;
	}

	ret = request_irq(hdmi_dev->int_irq, hdmi_irq_handler,
			0, "hdmi-int", hdmi_dev);
	if (ret) {
		dev_err(dev, "request int interrupt failed.\n");
		goto fail_switch;
	}
	disable_irq(hdmi_dev->int_irq);

	s5p_v4l2_int_src_ext_hpd();
	ret = request_irq(hdmi_dev->ext_irq, hdmi_irq_handler_ext,
			IRQ_TYPE_EDGE_BOTH, "hdmi-ext", hdmi_dev);
	if (ret) {
		dev_err(dev, "request ext interrupt failed.\n");
		goto fail_ext;
	}

	hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
	/* FIXME: missing fail preset is not supported */
	hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset);

	/* default audio configuration : disable audio */
	hdmi_dev->audio_enable = 0;
	hdmi_dev->audio_channel_count = 2;
	//hdmi_dev->sample_rate = DEFAULT_SAMPLE_RATE;
	hdmi_dev->sample_rate = 48000;
	hdmi_dev->sample_size = DEFAULT_SAMPLE_SIZE;
	hdmi_dev->color_range = HDMI_RGB709_0_255;
	hdmi_dev->bits_per_sample = DEFAULT_BITS_PER_SAMPLE;
	hdmi_dev->audio_codec = DEFAULT_AUDIO_CODEC;

	/* default aspect ratio is 16:9 */
	hdmi_dev->aspect = HDMI_ASPECT_RATIO_16_9;

	/* default HDMI streaming is stoped */
	hdmi_dev->streaming = HDMI_STOP;

	/* register hdmi subdev as entity */
	ret = hdmi_register_entity(hdmi_dev);
	if (ret)
		goto fail_irq;

	hdmi_entity_info_print(hdmi_dev);

	pm_runtime_enable(dev);

	//if {(edid_supports_hdmi(hdmi_dev)) {
#if 1 
		/* initialize hdcp resource */
		ret = hdcp_prepare(hdmi_dev);
		if (ret)
			goto fail_irq;
#endif
//	}

	/* work after booting */
	queue_delayed_work(system_nrt_wq, &hdmi_dev->hdmi_probe_work,
					msecs_to_jiffies(1500));
	queue_delayed_work(system_nrt_wq, &hdmi_dev->hpd_work_ext,
					msecs_to_jiffies(1500));

	dev_info(dev, "probe sucessful\n");

	hdmi_debugfs_init(hdmi_dev);

	return 0;

fail_irq:
	free_irq(hdmi_dev->ext_irq, hdmi_dev);

fail_ext:
	free_irq(hdmi_dev->int_irq, hdmi_dev);

fail_switch:
	switch_dev_unregister(&hdmi_dev->hpd_switch);

fail_vdev:
	v4l2_device_unregister(&hdmi_dev->v4l2_dev);

fail_lock:
	mutex_destroy(&hdmi_dev->mutex);

fail_regs:
	iounmap(hdmi_dev->regs);

fail_init:
	hdmi_resources_cleanup(hdmi_dev);

fail_hdev:
	kfree(hdmi_dev);

fail:
	dev_err(dev, "probe failed\n");
	return ret;
}
Ejemplo n.º 14
0
int msm_camera_flash_external(
	struct msm_camera_sensor_flash_external *external,
	unsigned led_state)
{
	int rc = 0;

	switch (led_state) {
//B 2012/07/22
#ifdef CONFIG_LEDS_LM3561
    case MSM_CAMERA_LED_INIT:
        lm3561 = lm3561_init();
        break;
    case MSM_CAMERA_LED_RELEASE:
        //B 2012/08/20
        lm3561_release(lm3561);
        lm3561 = NULL;
        //E 2012/08/20
        break;
    case MSM_CAMERA_LED_OFF:
        //B 2012/11/06
        if (flash_auto && board_type_with_hw_id() > DVT2_BOARD_HW_ID) {
            flash_auto = 0;
        } else {
            lm3561_flash_set(lm3561, 0);
        }
        //E 2012/11/06
        break;
    case MSM_CAMERA_LED_LOW:
        lm3561_torch_set(lm3561, 1);
        break;
    case MSM_CAMERA_LED_HIGH:
        //B 2012/11/06
        if (board_type_with_hw_id() <= DVT2_BOARD_HW_ID) {
            lm3561_flash_set(lm3561, 1);
        } else {
            msm_sensor_set_flash(1);
            flash_auto = 1;
        }
        //E 2012/11/06
        break;
    default:
        rc = -EFAULT;
        break;
#else
	case MSM_CAMERA_LED_INIT:
		if (external->flash_id == MAM_CAMERA_EXT_LED_FLASH_SC628A) {
			if (!sc628a_client) {
				rc = i2c_add_driver(&sc628a_i2c_driver);
				if (rc < 0 || sc628a_client == NULL) {
					pr_err("sc628a_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else if (external->flash_id ==
			MAM_CAMERA_EXT_LED_FLASH_TPS61310) {
			if (!tps61310_client) {
				rc = i2c_add_driver(&tps61310_i2c_driver);
				if (rc < 0 || tps61310_client == NULL) {
					pr_err("tps61310_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else {
			pr_err("Flash id not supported\n");
			rc = -ENOTSUPP;
			return rc;
		}

#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && !sx150x_client) {
			struct i2c_adapter *adapter =
			i2c_get_adapter(external->expander_info->bus_id);
			if (adapter)
				sx150x_client = i2c_new_device(adapter,
					external->expander_info->board_info);
			if (!sx150x_client || !adapter) {
				pr_err("sx150x_client is not available\n");
				rc = -ENOTSUPP;
				if (sc628a_client) {
					i2c_del_driver(&sc628a_i2c_driver);
					sc628a_client = NULL;
				}
				if (tps61310_client) {
					i2c_del_driver(&tps61310_i2c_driver);
					tps61310_client = NULL;
				}
				return rc;
			}
			i2c_put_adapter(adapter);
		}
#endif
		if (sc628a_client)
			rc = gpio_request(external->led_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_en, 0);
		} else {
			goto error;
		}

		if (sc628a_client)
			rc = gpio_request(external->led_flash_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_flash_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_flash_en, 0);
			break;
		}

		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
		}
error:
		pr_err("%s gpio request failed\n", __func__);
		if (sc628a_client) {
			i2c_del_driver(&sc628a_i2c_driver);
			sc628a_client = NULL;
		}
		if (tps61310_client) {
			i2c_del_driver(&tps61310_i2c_driver);
			tps61310_client = NULL;
		}
		break;

	case MSM_CAMERA_LED_RELEASE:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
			gpio_set_value_cansleep(external->led_flash_en, 0);
			gpio_free(external->led_flash_en);
			if (sc628a_client) {
				i2c_del_driver(&sc628a_i2c_driver);
				sc628a_client = NULL;
			}
			if (tps61310_client) {
				if (timer_state) {
					del_timer(&flash_timer);
					kfree((void *)work);
					timer_state = 0;
				}
				i2c_del_driver(&tps61310_i2c_driver);
				tps61310_client = NULL;
			}
		}
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && sx150x_client) {
			i2c_unregister_device(sx150x_client);
			sx150x_client = NULL;
		}
#endif
		break;

	case MSM_CAMERA_LED_OFF:
		if (sc628a_client || tps61310_client) {
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
				if (timer_state) {
					del_timer(&flash_timer);
					kfree((void *)work);
					timer_state = 0;
				}
			}
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_set_value_cansleep(external->led_flash_en, 0);
		}
		break;

	case MSM_CAMERA_LED_LOW:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x06, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x46, MSM_CAMERA_I2C_BYTE_DATA);
				flash_wq = alloc_workqueue("my_queue",WQ_MEM_RECLAIM,1);
				work = (struct flash_work *)kmalloc(sizeof(struct flash_work), GFP_KERNEL);
				INIT_WORK( (struct work_struct *)work, flash_wq_function );
				setup_timer(&flash_timer, flash_timer_callback, 0);
				mod_timer(&flash_timer, jiffies + msecs_to_jiffies(10000));
				timer_state = 1;
			}
		}
		break;

	case MSM_CAMERA_LED_HIGH:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x49, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x8B, MSM_CAMERA_I2C_BYTE_DATA);
			}
		}
		break;

	default:
		rc = -EFAULT;
		break;
#endif
//E 2012/07/22
	}
	return rc;
}
Ejemplo n.º 15
0
static int atomisp_subdev_probe(struct atomisp_device *isp)
{
	struct atomisp_platform_data *pdata = NULL;
	struct intel_v4l2_subdev_table *subdevs;
	struct v4l2_subdev *subdev = NULL;
	struct i2c_adapter *adapter = NULL;
	struct i2c_board_info *board_info;
	int raw_index = -1;

	/*
	 * fixing me!
	 * currently no function intel_get_v4l2_subdev_table()
	 * defined in board specific source code
	 */
#ifndef CONFIG_X86_MRFLD
	pdata = (struct atomisp_platform_data *)intel_get_v4l2_subdev_table();
#else
	pdata = NULL;
#endif
	if (pdata == NULL) {
		v4l2_err(&atomisp_dev, "no platform data available\n");
		return -ENODEV;
	}

	for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) {
		board_info = &subdevs->v4l2_subdev.board_info;

		adapter = i2c_get_adapter(subdevs->v4l2_subdev.i2c_adapter_id);
		if (adapter == NULL) {
			v4l2_err(&atomisp_dev,
				    "Failed to find i2c adapter for subdev %s\n"
				    , board_info->type);
			break;
		}

		subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
				board_info, NULL);

		if (subdev == NULL) {
			v4l2_warn(&atomisp_dev,
				    "Subdev %s detection fail\n",
				    board_info->type);
			continue;
		}

		v4l2_info(&atomisp_dev,
			    "Subdev %s successfully register\n",
			  board_info->type);

		switch (subdevs->type) {
		case RAW_CAMERA:
			raw_index = isp->input_cnt;
		case SOC_CAMERA:
			if (isp->input_cnt >= ATOM_ISP_MAX_INPUTS) {
				v4l2_warn(&atomisp_dev,
					"too many atomisp inputs, ignored\n");
				break;
			}

			isp->inputs[isp->input_cnt].type = subdevs->type;
			isp->inputs[isp->input_cnt].port = subdevs->port;
			isp->inputs[isp->input_cnt].camera = subdev;
			isp->inputs[isp->input_cnt].shading_table = NULL;
			isp->inputs[isp->input_cnt].morph_table = NULL;
			/*
			 * initialize the subdev frame size, then next we can
			 * judge whether frame_size store effective value via
			 * pixel_format.
			 */
			isp->inputs[isp->input_cnt].frame_size.pixel_format = 0;
			isp->input_cnt++;
			break;
		case CAMERA_MOTOR:
			isp->motor = subdev;
			break;
		case LED_FLASH:
		case XENON_FLASH:
			isp->flash = subdev;
			break;
		default:
			v4l2_dbg(1, dbg_level, &atomisp_dev,
				"unkonw subdev probed\n");
			break;
		}

	}

	/*
	 * HACK: Currently VCM belongs to primary sensor only, but correct
	 * approach must be to acquire from platform code which sensor
	 * owns it.
	 */
	if (isp->motor && raw_index >= 0)
		isp->inputs[raw_index].motor = isp->motor;

	/*Check camera for at least one subdev in it */
	if (!isp->inputs[0].camera) {
		v4l2_err(&atomisp_dev, "atomisp: "
		       "no camera attached or fail to detect\n");
		return -ENODEV;
	}
	return 0;
}
Ejemplo n.º 16
0
static void ssm2603_init(void)
{
	struct audio_codec_configuration ssm2603_config[] = {
		{0x06, 0xFF}, // power down all
		{0x06, 0x70}, // power up DEVICE, DAC, ADC, MIC, LINEIN
		{0x00, 0x17}, // ADC unmute LINEIN L+R
		{0x01, 0x17},
		{0x02, 0x6F}, // DAC volume L+R
		{0x03, 0x6F},
		{0x04, 0x13}, // use DACSEL, disable bypass
		{0x05, 0x06}, // unmute DAC, set de-emphasis rate
		//{0x07, 0x42}, // master and i2s mode - PCB FMC-HMI rev A
		{0x07, 0x02}, // slave and i2s mode - PCB FMC-HMI rev B
		{0x08, 0x01}, // sampling rate ADC and DAC, USB mode
		{0x09, 0x01}, // activate digital core
		{0x06, 0x60}, // enable DAC output path
	};
	struct i2c_adapter *adapter;
	struct i2c_msg msg;
	int i, ret;
	u8 data_buff[2];

	adapter = i2c_get_adapter(FMC2_I2C_ADAPTER_ID);
	if (!adapter) {
		pr_err("%s - no I2C device\n", __func__);
		return;
	}

	msg.addr = FMC2_I2C_SSM2603_ADDR;
	msg.flags = 0;
	msg.len = 0;
	msg.buf = data_buff;

	for(i = 0; i < ARRAY_SIZE(ssm2603_config); i++) {
		msg.buf[0] = (ssm2603_config[i].address<<1);
		msg.buf[1] = ssm2603_config[i].data;
		if (set_device_reg(adapter, &msg, 2) < 0)
			goto ssm2603_init_error;
	}
	// check register values
//	for (i = 0; i < 9; i++) {
//		msg.buf[0] = i<<1;
//		if (get_device_reg(adapter, &msg, 1))
//			printk(KERN_ERR "Error SSM2603 readback\n");
//		pr_info("read A 0x%X D 0x%X\n\r", i, msg.buf[0]);
//	}

	ret = gpio_request(FMC2_GPIO_AC_MUTE, "FMC2 AC mute");
	if (ret < 0)
		printk(KERN_ERR "Error requesting GPIO %d", ret);
	ret = gpio_direction_output(FMC2_GPIO_AC_MUTE, 1);
	if (ret)
		printk(KERN_ERR "Error setting GPIO \"out\" %d", ret);
	gpio_set_value(FMC2_GPIO_AC_MUTE, 1);
	gpio_free(FMC2_GPIO_AC_MUTE);
	mdelay(10);

	return;

ssm2603_init_error:
	pr_err("SSM2603 error at A 0x%X D 0x%X\n", msg.buf[0], msg.buf[1]);
}
Ejemplo n.º 17
0
int init_ci_controller(struct dvb_adapter* dvb_adap)
{
	struct ufs9xx_cic_state *state = &ci_state;
	struct ufs9xx_cic_core *core = &ci_core;
	int result;

	dprintk(1,"init_ufs9xx_cic >\n");

	core->dvb_adap = dvb_adap;

#if defined(UFS922) || defined(UFC960)
	state->i2c = i2c_get_adapter(2);
	state->i2c_addr = 0x23;

	state->slot_attribute_read[0]   = (volatile unsigned long) ioremap_nocache(0x02828000, 0x200);
	state->slot_attribute_write[0]  = (volatile unsigned long) ioremap_nocache(0x02808000, 0x200);
	state->slot_control_read[0]     = (volatile unsigned long) ioremap_nocache(0x02820000, 0x200);
	state->slot_control_write[0]    = (volatile unsigned long) ioremap_nocache(0x02800000, 0x200);

	state->slot_attribute_read[1]   = (volatile unsigned long) ioremap_nocache(0x02028000, 0x200);
	state->slot_attribute_write[1]  = (volatile unsigned long) ioremap_nocache(0x02008000, 0x200);
	state->slot_control_read[1]     = (volatile unsigned long) ioremap_nocache(0x02020000, 0x200);
	state->slot_control_write[1]    = (volatile unsigned long) ioremap_nocache(0x02000000, 0x200);

#elif defined(UFS913)
	state->slot_attribute_read[0]   = (volatile unsigned long) ioremap_nocache(0x04828000, 0x200);
	state->slot_attribute_write[0]  = (volatile unsigned long) ioremap_nocache(0x04808000, 0x200);
	state->slot_control_read[0]     = (volatile unsigned long) ioremap_nocache(0x04820000, 0x200);
	state->slot_control_write[0]    = (volatile unsigned long) ioremap_nocache(0x04800000, 0x200);

	state->slot_attribute_read[1]   = (volatile unsigned long) ioremap_nocache(0x05028000, 0x200);
	state->slot_attribute_write[1]  = (volatile unsigned long) ioremap_nocache(0x05008000, 0x200);
	state->slot_control_read[1]     = (volatile unsigned long) ioremap_nocache(0x05020000, 0x200);
	state->slot_control_write[1]    = (volatile unsigned long) ioremap_nocache(0x05000000, 0x200);

	ufs9xx_write_register_u32_map(0xfe000010, 0x0000c0de);
	ufs9xx_write_register_u32_map(0xfe000088, 0x00000000);
	ufs9xx_write_register_u32_map(0xfe000080, 0x00000019);
	ufs9xx_write_register_u32_map(0xfe000084, 0x00003334);
	ufs9xx_write_register_u32_map(0xfe00008c, 0x00000000);
	ufs9xx_write_register_u32_map(0xfe000088, 0x00000001);

	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x10c, 0x01);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x1b0, 0x53);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x1b2, 0x54);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x1b4, 0x41);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x1b6, 0x50);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x1b8, 0x49);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x170, 0x53);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x172, 0x44);
	ufs9xx_write_register_u8(state->slot_attribute_write[0] + 0x174, 0x4b);

	state->i2c = i2c_get_adapter(1);
	state->i2c_addr = 0x23;
#elif defined(UFS912)
	state->slot_attribute_read[0]   = (volatile unsigned long) ioremap_nocache(0x03028000, 0x200);
	state->slot_attribute_write[0]  = (volatile unsigned long) ioremap_nocache(0x03008000, 0x200);
	state->slot_control_read[0]     = (volatile unsigned long) ioremap_nocache(0x03020000, 0x200);
	state->slot_control_write[0]     = (volatile unsigned long) ioremap_nocache(0x03000000, 0x200);

	state->slot_attribute_read[1]   = (volatile unsigned long) ioremap_nocache(0x04028000, 0x200);
	state->slot_attribute_write[1]  = (volatile unsigned long) ioremap_nocache(0x04008000, 0x200);
	state->slot_control_read[1]     = (volatile unsigned long) ioremap_nocache(0x04020000, 0x200);
	state->slot_control_write[1]     = (volatile unsigned long) ioremap_nocache(0x04000000, 0x200);
#endif

	memset(&core->ca, 0, sizeof(struct dvb_ca_en50221));

	/* register CI interface */
	core->ca.owner = THIS_MODULE;

	core->ca.read_attribute_mem  = ufs9xx_cic_read_attribute_mem;
	core->ca.write_attribute_mem = ufs9xx_cic_write_attribute_mem;
	core->ca.read_cam_control 	 = ufs9xx_cic_read_cam_control;
	core->ca.write_cam_control 	 = ufs9xx_cic_write_cam_control;
	core->ca.slot_shutdown 		 = ufs9xx_cic_slot_shutdown;
	core->ca.slot_ts_enable 	 = ufs9xx_cic_slot_ts_enable;

	core->ca.slot_reset 		 = ufs9xx_cic_slot_reset;
	core->ca.poll_slot_status 	 = ufs9xx_cic_poll_slot_status;

	state->core 			     = core;
	core->ca.data 			     = state;

	cic_init_hw();
	
	dprintk(1, "init_ufs9xx_cic: call dvb_ca_en50221_init\n");

	if ((result = dvb_ca_en50221_init(core->dvb_adap,
					  &core->ca, 0, 2)) != 0) {
		printk(KERN_ERR "ca0 initialisation failed.\n");
		goto error;
	}

	dprintk(1, "ufs9xx_cic: ca0 interface initialised.\n");

	dprintk(10, "init_ufs9xx_cic <\n");

	return 0;

error:

	printk("init_ufs9xx_cic < error\n");

	return result;
}
Ejemplo n.º 18
0
static void vt1603_init(unsigned int i2c_adapter_id)
{
	struct audio_codec_configuration vt1603_config[] = {
		{0xc2, 0x01},
		{0x15, 0xff},  // Software reset for codec part
		{0x15, 0x00},
		{0x60, 0x04},  // Reset codec analog part
		{0x19, 0x2a},  //master mode 24bit  I2S
		{0x07, 0xc0},  //L 0dB
		{0x08, 0xc0},  //R 0dB
		{0x05, 0xc0},  //gain, update, pu aow, sample rate
		{0x0a, 0x41},  //hpf en(parameterized)
		{0x0b, 0x40},  //L2L, R2R, unmute
		{0x0c, 0x00},  //volume  -36dB
		{0x0f, 0x93},  //DRC disable,  DRC 48k SR
		{0x28, 0x00},  //EQ disable
		{0x40, 0x70},  //clk enable
		{0x41, 0x02},  //DAC_DIV=clk_sys/2
		{0x42, 0x07},  //bclk=clk_sys/8
		{0x62, 0xF4},  // Enable and un-mute DAC
		{0x68, 0x4c},  //100% HP local current, hp output enable and hp unmute
		//{0x6e, 0x34},  //NCP setting
		{0x69, 0x93},  // driver input select
		{0x7a, 0x18},
		{0x00, 0xd0},  //DC-Remove, 0dB shift gain
		{0x01, 0x57},  //unmute, LADC gain
		{0x02, 0x57},  //unmute, RADC gain
		{0x03, 0x04},  //48k SR, L2L, R2R
		{0x04, 0x00},  //default
		{0x60, 0xcc},  //vmid: 50k div, vref enable, micbias enable, mic_det enable
		{0x61, 0xf9},  // Enable VREF_SC_DA  4X/4 bias current
		{0x63, 0xe4},  //L/R ADC enable, 30u AAF local current, 50u SDM current
		{0x64, 0x17},  //Lpga gain=0dB, zero cross
		{0x65, 0x17},  //Rpga gain=0dB, zero cross
		{0x66, 0x1E},  //pga not mute, L/R analog in channel enable
		{0x8e, 0xCf},  //L/R input form micin enable, timeout enable
		{0x92, 0x0c},  //bandgap on(default), micbias=90%AVDD
		{0x88, 0x28},
		{0x19, 0x2A},  //full loop
		{0x93, 0x20},  //add offset
		{0x67, 0xf6},
		{0x25, 0x3c}
	};
	struct i2c_adapter *adapter;
	struct i2c_msg msg;
	int i;
	u8 data_buff[2];

	adapter = i2c_get_adapter(i2c_adapter_id);
	if (!adapter) {
		pr_err("%s - no I2C device\n", __func__);
		return;
	}

	msg.addr = I2C_VT1603_ADDR;
	msg.flags = 0;
	msg.len = 0;
	msg.buf = data_buff;

	for(i = 0; i < ARRAY_SIZE(vt1603_config); i++) {
		msg.buf[0] = vt1603_config[i].address;
		msg.buf[1] = vt1603_config[i].data;
		if (set_device_reg(adapter, &msg, 2) < 0)
			goto vt1603_init_error;
	}
	// check register values
//	for (i = 0; i < 197; i++) {
//		msg.buf[0] = i;
//		if (get_device_reg(adapter, &msg, 1))
//			printk(KERN_ERR "Error VT1603 readback\n");
//		pr_info("read A 0x%X D 0x%X\n\r", i, msg.buf[0]);
//	}

	return;

vt1603_init_error:
	pr_err("VT1603 error at A 0x%X D 0x%X\n", msg.buf[0], msg.buf[1]);
}
Ejemplo n.º 19
0
	/* CONFIG_N bit in SP_ILOCK register has to be cleared for new
	 * values in registers to be effective after writing to
	 * other registers.
	 */
	hsic_hub_clear_bits(client, SMSC3503_SP_ILOCK, CONFIG_N);

	return 0;
}

static int i2c_hsic_hub_remove(struct i2c_client *client)
{
	return 0;
}

static const struct i2c_device_id hsic_hub_id[] = {
	{"i2c_hsic_hub", 0},
	{}
};
MODULE_DEVICE_TABLE(i2c, hsichub_id);

static struct i2c_driver hsic_hub_driver = {
	.driver = {
		.name = "i2c_hsic_hub",
	},
	.probe    = i2c_hsic_hub_probe,
	.remove   = i2c_hsic_hub_remove,
	.id_table = hsic_hub_id,
};

#define HSIC_HUB_VDD_VOL_MIN	1650000 /* uV */
#define HSIC_HUB_VDD_VOL_MAX	1950000 /* uV */
#define HSIC_HUB_VDD_LOAD	36000	/* uA */
static int __devinit smsc_hub_probe(struct platform_device *pdev)
{
	int ret = 0;
	const struct smsc_hub_platform_data *pdata;
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;

	if (!pdev->dev.platform_data) {
		dev_err(&pdev->dev, "No platform data\n");
		return -ENODEV;
	}

	pdata = pdev->dev.platform_data;
	if (!pdata->hub_reset)
		return -EINVAL;

	smsc_hub = kzalloc(sizeof(*smsc_hub), GFP_KERNEL);
	if (!smsc_hub)
		return -ENOMEM;

	smsc_hub->hsic_hub_reg = regulator_get(&pdev->dev, "EXT_HUB_VDDIO");
	if (IS_ERR(smsc_hub->hsic_hub_reg)) {
		dev_err(&pdev->dev, "unable to get ext hub vddcx\n");
		ret = PTR_ERR(smsc_hub->hsic_hub_reg);
		goto free_mem;
	}

	ret = gpio_request(pdata->hub_reset, "HSIC_HUB_RESET_GPIO");
	if (ret < 0) {
		dev_err(&pdev->dev, "gpio request failed for GPIO%d\n",
							pdata->hub_reset);
		goto gpio_req_fail;
	}

	ret = regulator_set_voltage(smsc_hub->hsic_hub_reg,
			HSIC_HUB_VDD_VOL_MIN,
			HSIC_HUB_VDD_VOL_MAX);
	if (ret) {
		dev_err(&pdev->dev, "unable to set the voltage"
				"for hsic hub reg\n");
		goto reg_set_voltage_fail;
	}

	ret = regulator_set_optimum_mode(smsc_hub->hsic_hub_reg,
				HSIC_HUB_VDD_LOAD);
	if (ret < 0) {
		dev_err(&pdev->dev, "Unable to set optimum mode of regulator:"
							"VDDCX\n");
		goto reg_optimum_mode_fail;
	}

	ret = regulator_enable(smsc_hub->hsic_hub_reg);
	if (ret) {
		dev_err(&pdev->dev, "unable to enable ext hub vddcx\n");
		goto reg_enable_fail;
	}

	smsc_hub->xo_handle = msm_xo_get(MSM_XO_TCXO_D1, "hsic_hub");
	if (IS_ERR(smsc_hub->xo_handle)) {
		dev_err(&pdev->dev, "not able to get the handle"
					 "for TCXO D1 buffer\n");
			goto disable_regulator;
	}

	ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_ON);
	if (ret) {
		dev_err(&pdev->dev, "failed to vote for TCXO"
			"D1 buffer\n");
		goto xo_vote_fail;
	}

	gpio_direction_output(pdata->hub_reset, 0);
	/* Hub reset should be asserted for minimum 2microsec
	 * before deasserting.
	 */
	udelay(5);
	gpio_direction_output(pdata->hub_reset, 1);

	ret = i2c_add_driver(&hsic_hub_driver);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n");
		goto i2c_add_fail;
	}
	usleep_range(10000, 12000);
	i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID);

	if (!i2c_adap) {
		dev_err(&pdev->dev, "failed to get i2c adapter\n");
		i2c_del_driver(&hsic_hub_driver);
		goto i2c_add_fail;
	}

	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE);

	smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c, NULL);
	i2c_put_adapter(i2c_adap);
	if (!smsc_hub->client)
		dev_err(&pdev->dev, "failed to connect to smsc_hub"
			 "through I2C\n");

i2c_add_fail:
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

xo_vote_fail:
	msm_xo_put(smsc_hub->xo_handle);
disable_regulator:
	regulator_disable(smsc_hub->hsic_hub_reg);
reg_enable_fail:
	regulator_set_optimum_mode(smsc_hub->hsic_hub_reg, 0);
reg_optimum_mode_fail:
	regulator_set_voltage(smsc_hub->hsic_hub_reg, 0,
				HSIC_HUB_VDD_VOL_MIN);
reg_set_voltage_fail:
	gpio_free(pdata->hub_reset);
gpio_req_fail:
	regulator_put(smsc_hub->hsic_hub_reg);
free_mem:
	kfree(smsc_hub);

	return ret;
}
Ejemplo n.º 20
0
static void ssm2603_set_sample_rate(int sample_rate)
{
	struct i2c_adapter *adapter;
	struct i2c_msg msg;
	u8 data_buff[2];

	adapter = i2c_get_adapter(FMC2_I2C_ADAPTER_ID);
	if (!adapter) {
		pr_err("%s - no I2C device\n", __func__);
		return;
	}

	msg.addr = FMC2_I2C_SSM2603_ADDR;
	msg.flags = 0;
	msg.len = 0;
	msg.buf = data_buff;

	msg.buf[0] = (0x06<<1);
	// power down, DAC, ADC, MIC, LINEIN
	msg.buf[1] = 0x70;
	if (set_device_reg(adapter, &msg, 2) < 0) {
		goto ssm2603_set_sample_rate_error;
	}
	// sampling rate ADC and DAC, USB mode for 12MHz system clock
	msg.buf[0] = (0x08<<1);
	switch (sample_rate) {
	case 8000:
		msg.buf[1] = 0x0D; //8kHz : 8kHz
		break;
	case 11025:
		msg.buf[1] = 0x33; //11.025kHz : 11.025kHz
		break;
	case 16000:
		msg.buf[1] = 0x29; //16kHz : 16kHz
		break;
	case 22050:
		msg.buf[1] = 0x37; //22.050kHz : 22.050kHz
		break;
	case 44100:
		msg.buf[1] = 0x23; //44.1kHz : 44.1kHz
		break;
	case 48000:
		msg.buf[1] = 0x01; //48kHz : 48kHz
		break;
	case 96000:
		msg.buf[1] = 0x1D; //96kHz : 96kHz
		break;
	default:
		pr_err("Sample rate %d not supported\n", sample_rate);
		pr_info("Set to default 48kHz\n");
		msg.buf[1] = 0x01; //48kHz : 48kHz
		break;
	}

	if (set_device_reg(adapter, &msg, 2) < 0) {
		goto ssm2603_set_sample_rate_error;
	}
	// wait at least 73ms (10.1uF * 25000/3.5)
	mdelay(100);
	// enable DAC output path
	msg.buf[0] = (0x06<<1);
	msg.buf[1] = 0x60;
	if (set_device_reg(adapter, &msg, 2) < 0) {
		goto ssm2603_set_sample_rate_error;
	}

	return;

ssm2603_set_sample_rate_error:
	pr_err("SSM2603 set sample rate error at A 0x%X D 0x%X\n",
		msg.buf[0], msg.buf[1]);
}
static __init int vpif_probe(struct platform_device *pdev)
{
	struct vpif_subdev_info *subdevdata;
	struct vpif_capture_config *config;
	int i, j, k, m, q, err;
	struct i2c_adapter *i2c_adap;
	struct channel_obj *ch;
	struct common_obj *common;
	struct video_device *vfd;
	struct resource *res;
	int subdev_count;

	vpif_dev = &pdev->dev;

	err = initialize_vpif();
	if (err) {
		v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
		return err;
	}

	k = 0;
	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
		for (i = res->start; i <= res->end; i++) {
			if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
					"DM646x_Capture",
				(void *)(&vpif_obj.dev[k]->channel_id))) {
				err = -EBUSY;
				i--;
				goto vpif_int_err;
			}
		}
		k++;
	}

	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
		/* Get the pointer to the channel object */
		ch = vpif_obj.dev[i];
		/* Allocate memory for video device */
		vfd = video_device_alloc();
		if (NULL == vfd) {
			for (j = 0; j < i; j++) {
				ch = vpif_obj.dev[j];
				video_device_release(ch->video_dev);
			}
			err = -ENOMEM;
			goto vpif_dev_alloc_err;
		}

		/* Initialize field of video device */
		*vfd = vpif_video_template;
		vfd->v4l2_dev = &vpif_obj.v4l2_dev;
		vfd->release = video_device_release;
		snprintf(vfd->name, sizeof(vfd->name),
			 "DM646x_VPIFCapture_DRIVER_V%d.%d.%d",
			 (VPIF_CAPTURE_VERSION_CODE >> 16) & 0xff,
			 (VPIF_CAPTURE_VERSION_CODE >> 8) & 0xff,
			 (VPIF_CAPTURE_VERSION_CODE) & 0xff);
		/* Set video_dev to the video device */
		ch->video_dev = vfd;
	}

	for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
		ch = vpif_obj.dev[j];
		ch->channel_id = j;
		common = &(ch->common[VPIF_VIDEO_INDEX]);
		spin_lock_init(&common->irqlock);
		mutex_init(&common->lock);
		/* Initialize prio member of channel object */
		v4l2_prio_init(&ch->prio);
		err = video_register_device(ch->video_dev,
					    VFL_TYPE_GRABBER, (j ? 1 : 0));
		if (err)
			goto probe_out;

		video_set_drvdata(ch->video_dev, ch);

	}

	i2c_adap = i2c_get_adapter(1);
	config = pdev->dev.platform_data;

	subdev_count = config->subdev_count;
	vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
				GFP_KERNEL);
	if (vpif_obj.sd == NULL) {
		vpif_err("unable to allocate memory for subdevice pointers\n");
		err = -ENOMEM;
		goto probe_out;
	}

	err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
	if (err) {
		v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
		goto probe_subdev_out;
	}

	for (i = 0; i < subdev_count; i++) {
		subdevdata = &config->subdev_info[i];
		vpif_obj.sd[i] =
			v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
						  i2c_adap,
						  subdevdata->name,
						  &subdevdata->board_info,
						  NULL);

		if (!vpif_obj.sd[i]) {
			vpif_err("Error registering v4l2 subdevice\n");
			goto probe_subdev_out;
		}
		v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
			  subdevdata->name);

		if (vpif_obj.sd[i])
			vpif_obj.sd[i]->grp_id = 1 << i;
	}
	v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver"
		  " initialized\n");

	return 0;

probe_subdev_out:
	/* free sub devices memory */
	kfree(vpif_obj.sd);

	j = VPIF_CAPTURE_MAX_DEVICES;
probe_out:
	v4l2_device_unregister(&vpif_obj.v4l2_dev);
	for (k = 0; k < j; k++) {
		/* Get the pointer to the channel object */
		ch = vpif_obj.dev[k];
		/* Unregister video device */
		video_unregister_device(ch->video_dev);
	}

vpif_dev_alloc_err:
	k = VPIF_CAPTURE_MAX_DEVICES-1;
	res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
	i = res->end;

vpif_int_err:
	for (q = k; q >= 0; q--) {
		for (m = i; m >= (int)res->start; m--)
			free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));

		res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
		if (res)
			i = res->end;
	}
	return err;
}
Ejemplo n.º 22
0
static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
{
    struct usb_hcd *hcd = 0;
    struct ohci_hcd *ohci;
    const struct hc_driver *driver = &ohci_pnx4008_hc_driver;
    struct i2c_adapter *i2c_adap;
    struct i2c_board_info i2c_info;

    int ret = 0, irq;

    dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (pnx4008)\n", hcd_name);
    if (usb_disabled()) {
        err("USB is disabled");
        ret = -ENODEV;
        goto out;
    }

    if (pdev->num_resources != 2
            || pdev->resource[0].flags != IORESOURCE_MEM
            || pdev->resource[1].flags != IORESOURCE_IRQ) {
        err("Invalid resource configuration");
        ret = -ENODEV;
        goto out;
    }

    /* Enable AHB slave USB clock, needed for further USB clock control */
    __raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL);

    ret = i2c_add_driver(&isp1301_driver);
    if (ret < 0) {
        err("failed to add ISP1301 driver");
        goto out;
    }
    i2c_adap = i2c_get_adapter(2);
    memset(&i2c_info, 0, sizeof(struct i2c_board_info));
    strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE);
    isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
                         normal_i2c, NULL);
    i2c_put_adapter(i2c_adap);
    if (!isp1301_i2c_client) {
        err("failed to connect I2C to ISP1301 USB Transceiver");
        ret = -ENODEV;
        goto out_i2c_driver;
    }

    isp1301_configure();

    /* Enable USB PLL */
    usb_clk = clk_get(&pdev->dev, "ck_pll5");
    if (IS_ERR(usb_clk)) {
        err("failed to acquire USB PLL");
        ret = PTR_ERR(usb_clk);
        goto out1;
    }

    ret = clk_enable(usb_clk);
    if (ret < 0) {
        err("failed to start USB PLL");
        goto out2;
    }

    ret = clk_set_rate(usb_clk, 48000);
    if (ret < 0) {
        err("failed to set USB clock rate");
        goto out3;
    }

    __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);

    /* Set to enable all needed USB clocks */
    __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL);

    while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) !=
            USB_CLOCK_MASK) ;

    hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
    if (!hcd) {
        err("Failed to allocate HC buffer");
        ret = -ENOMEM;
        goto out3;
    }

    /* Set all USB bits in the Start Enable register */
    pnx4008_set_usb_bits();

    hcd->rsrc_start = pdev->resource[0].start;
    hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
    if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
        dev_dbg(&pdev->dev, "request_mem_region failed\n");
        ret =  -ENOMEM;
        goto out4;
    }
    hcd->regs = (void __iomem *)pdev->resource[0].start;

    irq = platform_get_irq(pdev, 0);
    if (irq < 0) {
        ret = -ENXIO;
        goto out4;
    }

    pnx4008_start_hc();
    platform_set_drvdata(pdev, hcd);
    ohci = hcd_to_ohci(hcd);
    ohci_hcd_init(ohci);

    dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
    ret = usb_add_hcd(hcd, irq, 0);
    if (ret == 0)
        return ret;

    pnx4008_stop_hc();
out4:
    pnx4008_unset_usb_bits();
    usb_put_hcd(hcd);
out3:
    clk_disable(usb_clk);
out2:
    clk_put(usb_clk);
out1:
    i2c_unregister_device(isp1301_i2c_client);
    isp1301_i2c_client = NULL;
out_i2c_driver:
    i2c_del_driver(&isp1301_driver);
out:
    return ret;
}
Ejemplo n.º 23
0
static int __devinit toh_probe(struct platform_device *pdev)
{
    struct toh_data *toh = &other_half;
    struct i2c_adapter *i2c_adap;
    struct toh_platform_data *pdata = pdev->dev.platform_data;
    ssize_t count = 0;
    int ret = 0;
    char buf;

    toh->i2c_bus = pdata->i2c_bus;
    toh->eeprom = toh_eeprom;
    toh->macc = NULL;
    toh->dev = &pdev->dev;

    toh->vdd = regulator_get(toh->dev, "toh_vdd");

    if (IS_ERR(toh->vdd)) {
        dev_err(toh->dev, "Could not find toh_vdd regulator\n");
        ret = PTR_ERR(toh->vdd);
        goto probe_exit;
    }

    ret = regulator_enable(toh->vdd);
    if (ret) {
        dev_err(toh->dev, "Could not enable regulator\n");
        goto regulator_err;
    }

    i2c_adap = i2c_get_adapter(toh->i2c_bus);
    if (!i2c_adap) {
        ret = -ENODEV;
        dev_err(toh->dev, "Could not find I2C bus %d\n",
                toh->i2c_bus);
        goto i2c_err;
    }

    /* toh_setup_eeprom gets called as result of this */
    toh->i2c_dev = i2c_new_device(i2c_adap, &toh_i2c_eeprom_info);
    if (!toh->i2c_dev) {
        ret = -ENOMEM;
        dev_err(toh->dev, "Not enough memory for eeprom device %d\n",
                toh->i2c_bus);
        goto i2c_err;
    }

    /* Test if the eeprom is really readable / present on the cover */
    count = toh_eeprom_read(toh, &buf, 1, 1);

    regulator_disable(toh->vdd);

    if (count <= 0) {
        /* No eeprom on this cover, note this is a valid condition */
        dev_info(toh->dev, "No valid eeprom present\n");
        toh->sysfs_enabled = 0;
    } else {
        toh_eeprom_read_entry(toh, &toh->cfg_addr, TOH_EEPROM_CFG_ADDR);
        toh_eeprom_read_entry(toh, &toh->cfg_size, TOH_EEPROM_CFG_SIZE);
        toh_eeprom_read_entry(toh, &toh->eeprom_size,
                              TOH_EEPROM_EEPROM_SIZE);
        toh_eeprom_read_entry(toh, &toh->udata_addr,
                              TOH_EEPROM_UDATA_ADDR);
        toh_sysfs_create(toh);
        toh->sysfs_enabled = 1;
    }

    platform_set_drvdata(pdev, toh);
    dev_dbg(toh->dev, "TOH driver probed succesfully");

    return ret;

i2c_err:
    regulator_disable(toh->vdd);
regulator_err:
    regulator_put(toh->vdd);
probe_exit:
    return ret;
}
Ejemplo n.º 24
0
	struct i2c_msg msgs[] = { 
		{
			.addr   = addr,
			.flags  = 0,
			.len    = 1,
			.buf    = &reg,

		},
		{
			.addr   = addr,
			.flags  = I2C_M_RD,
			.len    = size,
			.buf    = data,
		}
	};
	adapter = i2c_get_adapter(IIC_ADAPTER);
	if (!adapter){
		return -1; 
	}
 	ret = i2c_transfer(adapter, msgs, 2);
	if ( ret != 2 ){
		return -1; 
	}

	return 0;
}

int cam_reg_write(unsigned char addr, unsigned char * data, int size)
{
	struct i2c_adapter *adapter;
	unsigned int ret;
Ejemplo n.º 25
0
BAREBOX_CMD_END

static int do_i2c_write(int argc, char *argv[])
{
	struct i2c_adapter *adapter = NULL;
	struct i2c_client client;
	int addr = -1, reg = -1, count = -1, verbose = 0, ret, opt, i, bus = 0, wide = 0;
	u8 *buf;

	while ((opt = getopt(argc, argv, "a:b:r:v:w")) > 0) {
		switch (opt) {
		case 'a':
			addr = simple_strtol(optarg, NULL, 0);
			break;
		case 'r':
			reg = simple_strtol(optarg, NULL, 0);
			break;
		case 'b':
			bus = simple_strtoul(optarg, NULL, 0);
			break;
		case 'v':
			verbose = 1;
			break;
		case 'w':
			wide = 1;
			break;
		}
	}

	count = argc - optind;

	if ((addr < 0) || (reg < 0) || (count == 0) || (addr > 0x7F))
		return COMMAND_ERROR_USAGE;

	adapter = i2c_get_adapter(bus);
	if (!adapter) {
		printf("i2c bus %d not found\n", bus);
		return -ENODEV;
	}

	client.adapter = adapter;
	client.addr = addr;

	buf = xmalloc(count);
	for (i = 0; i < count; i++)
		*(buf + i) = (char) simple_strtol(argv[optind+i], NULL, 16);

	ret = i2c_write_reg(&client, reg | (wide ? I2C_ADDR_16_BIT : 0), buf, count);
	if (ret != count)
		goto out;
	ret = 0;

	if (verbose) {
		printf("wrote %i bytes starting at reg 0x%04x to i2cdev 0x%02x on bus %i\n",
			count, reg, addr, adapter->nr);
		for (i = 0; i < count; i++)
			printf("0x%02x ", *(buf + i));
		printf("\n");
	}

out:
	free(buf);
	return ret;
}
Ejemplo n.º 26
0
int msm_camera_flash_external(
	struct msm_camera_sensor_flash_external *external,
	unsigned led_state)
{
	int rc = 0;

#if defined CONFIG_MSM_CAMERA_FLASH_SC628A
	switch (led_state) {

	case MSM_CAMERA_LED_INIT:
			if (!sc628a_client) {
				rc = i2c_add_driver(&sc628a_i2c_driver);
				if (rc < 0 || sc628a_client == NULL) {
					rc = -ENOTSUPP;
				CDBG("I2C add driver failed");
					return rc;
				}
			}
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && !sx150x_client) {
			struct i2c_adapter *adapter =
			i2c_get_adapter(external->expander_info->bus_id);
			if (adapter)
				sx150x_client = i2c_new_device(adapter,
					external->expander_info->board_info);
			if (!sx150x_client || !adapter) {
				rc = -ENOTSUPP;
					i2c_del_driver(&sc628a_i2c_driver);
					sc628a_client = NULL;
				return rc;
			}
		}
#endif
			rc = gpio_request(external->led_en, "sc628a");
		if (!rc) {
			gpio_direction_output(external->led_en, 1);
		} else {
			goto err1;
		}
			rc = gpio_request(external->led_flash_en, "sc628a");
		if (!rc) {
			gpio_direction_output(external->led_flash_en, 1);
			break;
		}

		gpio_set_value_cansleep(external->led_en, 0);
		gpio_free(external->led_en);

err1:
			i2c_del_driver(&sc628a_i2c_driver);
			sc628a_client = NULL;

		break;

	case MSM_CAMERA_LED_RELEASE:
		if (sc628a_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
			gpio_set_value_cansleep(external->led_flash_en, 0);
			gpio_free(external->led_flash_en);
		}
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && sx150x_client) {
			i2c_unregister_device(sx150x_client);
			sx150x_client = NULL;
		}
#endif
		break;

	case MSM_CAMERA_LED_OFF:
		rc = sc628a_i2c_write_b_flash(0x02, 0x0);
		if (sc628a_client) {
		gpio_set_value_cansleep(external->led_en, 0);
		gpio_set_value_cansleep(external->led_flash_en, 0);
		}
		break;

	case MSM_CAMERA_LED_LOW:
		if (sc628a_client) {
		gpio_set_value_cansleep(external->led_en, 1);
		gpio_set_value_cansleep(external->led_flash_en, 1);
		usleep_range(2000, 3000);
		}
		rc = sc628a_i2c_write_b_flash(0x02, 0x06);
		break;

	case MSM_CAMERA_LED_HIGH:
		if (sc628a_client) {
		gpio_set_value_cansleep(external->led_en, 1);
		gpio_set_value_cansleep(external->led_flash_en, 1);
		usleep_range(2000, 3000);
		}
		rc = sc628a_i2c_write_b_flash(0x02, 0x49);
		break;

	default:
		rc = -EFAULT;
		break;
	}
#endif

	return rc;
}
Ejemplo n.º 27
0
static int marimba_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct marimba_platform_data *pdata = client->dev.platform_data;
	struct i2c_adapter *ssbi_adap;
	struct marimba *marimba;
	int i, status;

	if (!pdata) {
		dev_dbg(&client->dev, "no platform data?\n");
		return -EINVAL;
	}

	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
		dev_dbg(&client->dev, "can't talk I2C?\n");
		return -EIO;
	}

	if (inuse) {
		dev_dbg(&client->dev, "driver already in use\n");
		return -EBUSY;
	}

	for (i = 0; i <= NUM_ADD; i++) {
		marimba = &marimba_modules[i];

		if (i == 0)
			marimba->client = client;
		else {
			if (i != MARIMBA_ID_TSADC)
				marimba->client = i2c_new_dummy(client->adapter,
							pdata->slave_id[i]);
			else {
				ssbi_adap = i2c_get_adapter(MARIMBA_SSBI_ADAP);
				marimba->client = i2c_new_dummy(ssbi_adap,
							pdata->slave_id[i]);
			}

			if (!marimba->client) {
				dev_err(&marimba->client->dev,
					"can't attach client %d\n", i);
				status = -ENOMEM;
				goto fail;
			}
			strlcpy(marimba->client->name, id->name,
						sizeof(marimba->client->name));
		}

		mutex_init(&marimba->xfer_lock);
	}

	inuse = true;

	if (pdata->marimba_setup != NULL)
		pdata->marimba_setup();

	marimba_init_reg(client);

	status = marimba_add_child(pdata);

	return 0;

fail:
	return status;
}
int __init init_display_devices(void)
{
	int ret;

#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_VSYNC
	struct i2c_adapter *i2c0;
#endif

	ret = fb_register_client(&framebuffer_nb);
	if (ret)
		pr_warning("Failed to register framebuffer notifier\n");

	ret = mcde_dss_register_notifier(&display_nb);
	if (ret)
		pr_warning("Failed to register dss notifier\n");

#ifdef CONFIG_DISPLAY_GENERIC_PRIMARY
	if (machine_is_hrefv60())
		generic_display0_pdata.reset_gpio = HREFV60_DISP1_RST_GPIO;
	else
		generic_display0_pdata.reset_gpio = EGPIO_PIN_15;

#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_VSYNC
	i2c0 = i2c_get_adapter(0);
	if (i2c0) {
		/*
		* U8500-UIB has the TC35893 at 0x44 on I2C0, the
		* ST-UIB has not.
		*/
		ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0,
							I2C_SMBUS_QUICK, NULL);
		i2c_put_adapter(i2c0);

		/* ret == 0 => U8500 UIB connected */
		generic_display0.synchronized_update = (ret == 0);
	}
#endif

	if (display_initialized_during_boot)
		generic_display0.power_mode = MCDE_DISPLAY_PM_STANDBY;
	ret = mcde_display_device_register(&generic_display0);
	if (ret)
		pr_warning("Failed to register generic display device 0\n");
#endif

#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY
	if (machine_is_hrefv60())
		generic_subdisplay_pdata.reset_gpio = HREFV60_DISP2_RST_GPIO;
	else
		generic_subdisplay_pdata.reset_gpio = EGPIO_PIN_14;
	ret = mcde_display_device_register(&generic_subdisplay);
	if (ret)
		pr_warning("Failed to register generic sub display device\n");
#endif

#ifdef CONFIG_DISPLAY_AV8100_TERTIARY
	INIT_DELAYED_WORK_DEFERRABLE(&work_dispreg_hdmi,
			delayed_work_dispreg_hdmi);

	schedule_delayed_work(&work_dispreg_hdmi,
			msecs_to_jiffies(DISPREG_HDMI_DELAY));
#endif
#ifdef CONFIG_DISPLAY_AB8500_TERTIARY
	ret = mcde_display_device_register(&tvout_ab8500_display);
	if (ret)
		pr_warning("Failed to register ab8500 tvout device\n");
#endif

	return ret;
}
Ejemplo n.º 29
0
int msm_camera_flash_external(
	struct msm_camera_sensor_flash_external *external,
	unsigned led_state)
{
	int rc = 0;

	switch (led_state) {

	case MSM_CAMERA_LED_INIT:
		if (external->flash_id == MAM_CAMERA_EXT_LED_FLASH_SC628A) {
			if (!sc628a_client) {
				rc = i2c_add_driver(&sc628a_i2c_driver);
				if (rc < 0 || sc628a_client == NULL) {
					pr_err("sc628a_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else if (external->flash_id ==
			MAM_CAMERA_EXT_LED_FLASH_TPS61310) {
			if (!tps61310_client) {
				rc = i2c_add_driver(&tps61310_i2c_driver);
				if (rc < 0 || tps61310_client == NULL) {
					pr_err("tps61310_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else {
			pr_err("Flash id not supported\n");
			rc = -ENOTSUPP;
			return rc;
		}

#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && !sx150x_client) {
			struct i2c_adapter *adapter =
			i2c_get_adapter(external->expander_info->bus_id);
			if (adapter)
				sx150x_client = i2c_new_device(adapter,
					external->expander_info->board_info);
			if (!sx150x_client || !adapter) {
				pr_err("sx150x_client is not available\n");
				rc = -ENOTSUPP;
				if (sc628a_client) {
					i2c_del_driver(&sc628a_i2c_driver);
					sc628a_client = NULL;
				}
				if (tps61310_client) {
					i2c_del_driver(&tps61310_i2c_driver);
					tps61310_client = NULL;
				}
				return rc;
			}
			i2c_put_adapter(adapter);
		}
#endif
		if (sc628a_client)
			rc = gpio_request(external->led_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_en, 0);
		} else {
			goto error;
		}

		if (sc628a_client)
			rc = gpio_request(external->led_flash_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_flash_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_flash_en, 0);
			break;
		}

		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
		}
error:
		pr_err("%s gpio request failed\n", __func__);
		if (sc628a_client) {
			i2c_del_driver(&sc628a_i2c_driver);
			sc628a_client = NULL;
		}
		if (tps61310_client) {
			i2c_del_driver(&tps61310_i2c_driver);
			tps61310_client = NULL;
		}
		break;

	case MSM_CAMERA_LED_RELEASE:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
			gpio_set_value_cansleep(external->led_flash_en, 0);
			gpio_free(external->led_flash_en);
			if (sc628a_client) {
				i2c_del_driver(&sc628a_i2c_driver);
				sc628a_client = NULL;
			}
			if (tps61310_client) {
				i2c_del_driver(&tps61310_i2c_driver);
				tps61310_client = NULL;
			}
		}
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && sx150x_client) {
			i2c_unregister_device(sx150x_client);
			sx150x_client = NULL;
		}
#endif
		break;

	case MSM_CAMERA_LED_OFF:
		if (sc628a_client || tps61310_client) {
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
			}
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_set_value_cansleep(external->led_flash_en, 0);
		}
		break;

	case MSM_CAMERA_LED_LOW:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x06, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x86, MSM_CAMERA_I2C_BYTE_DATA);
			}
		}
		break;

	case MSM_CAMERA_LED_HIGH:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x49, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x8B, MSM_CAMERA_I2C_BYTE_DATA);
			}
		}
		break;

	default:
		rc = -EFAULT;
		break;
	}
	return rc;
}
static int tegra_camera_enable(struct nvhost_device *ndev)
{
	struct i2c_adapter *adapter;
	struct i2c_board_info port_expander_info = {
		I2C_BOARD_INFO("tca6416",
			       TEGRA_CAMERA_I2C_ADDR_PORT_EXPANDER) };
	struct i2c_board_info port_switch_info = {
		I2C_BOARD_INFO("pca9546",
			       TEGRA_CAMERA_I2C_ADDR_PORT_SWITCH) };
	int err;
	u16 val;
	u8 val2;

	/* Turn on relevant clocks. */
	clk_enable(clk_vi);
	clk_enable(clk_vi_sensor);
	clk_enable(clk_csi);
	clk_enable(clk_isp);
	clk_enable(clk_csus);

	/* Turn on power to the camera board. */
	regulator = regulator_get(&ndev->dev, "vddio_vi");
	if (IS_ERR(regulator)) {
		dev_info(&ndev->dev, "regulator_get() returned error %ld\n",
			 PTR_ERR(regulator));
		err = PTR_ERR(regulator);
		goto exit;
	}

	err = regulator_enable(regulator);
	if (err != 0)
		goto exit_regulator_put;

	/* Get the I2C adapter and clients for the stuff on the camera board. */
	adapter = i2c_get_adapter(TEGRA_CAMERA_I2C_ADAPTER_ID);
	if (!adapter) {
		err = -EINVAL;
		goto exit_regulator_disable;
	}

	port_expander = i2c_new_device(adapter, &port_expander_info);
	if (!port_expander) {
		err = -EINVAL;
		goto exit_adapter_put;
	}

	port_switch = i2c_new_device(adapter, &port_switch_info);
	if (!port_switch) {
		err = -EINVAL;
		goto exit_port_expander_unregister;
	}

	/* Set up GPIOs. */
	err = gpio_request(TEGRA_CAMERA_GPIO_CAM_PWR_EN, "cam_pwr_en");
	if (err != 0)
		goto exit_port_switch_unregister;
	gpio_direction_output(TEGRA_CAMERA_GPIO_CAM_PWR_EN, 1);

	err = gpio_request(TEGRA_CAMERA_GPIO_VI_GP3, "vi_gp3");
	if (err != 0)
		goto exit_gpio_free_cam_pwr_en;
	gpio_direction_output(TEGRA_CAMERA_GPIO_VI_GP3, 1);

	err = gpio_request(TEGRA_CAMERA_GPIO_PMU, "tegra_camera");
	if (err != 0)
		goto exit_gpio_free_vi_gp3;
	gpio_direction_output(TEGRA_CAMERA_GPIO_PMU, 1);

	/* All port pins on the port expander are inputs by default.
	 * Set all to output.
	 */
	i2c_smbus_write_word_data(port_expander, TCA6416_REG_CNF, 0x0000);

	/* Take port switch out of reset and turn on camera 3. */
	val = TCA6416_PORT_CAM3_RST |
	      TCA6416_PORT_TP_CAM3_AF_PWDN |
	      TCA6416_PORT_CAM3_LDO_SHDN |
	      TCA6416_PORT_CAM_I2C_MUX_RST |
	      TCA6416_PORT_CAM_LED1;
	i2c_smbus_write_word_data(port_expander, TCA6416_REG_OUTP, val);

	tegra_camera_dump_port_expander_regs(ndev);

	/* Twiddle port switch to select our camera. */
	val2 = i2c_smbus_read_byte(port_switch);
	val2 |= (1 << 2); /* Enable port 2 (out of 0..3). */
	i2c_smbus_write_byte(port_switch, val2);

	tegra_camera_dump_port_switch_regs(ndev);

	/* Give the sensor time to come out of reset.  The OV9740 needs
	 * 8192 clock cycles (from vi_sensor clock) before the first I2C
	 * transaction.
	 */
	udelay(1000);

	return 0;

exit_gpio_free_vi_gp3:
	gpio_free(TEGRA_CAMERA_GPIO_VI_GP3);
exit_gpio_free_cam_pwr_en:
	gpio_free(TEGRA_CAMERA_GPIO_CAM_PWR_EN);
exit_port_switch_unregister:
	i2c_unregister_device(port_switch);
exit_port_expander_unregister:
	i2c_unregister_device(port_expander);
exit_adapter_put:
	i2c_put_adapter(adapter);
exit_regulator_disable:
	regulator_disable(regulator);
exit_regulator_put:
	regulator_put(regulator);
exit:
	return err;
}