static void max77660_haptic_play_effect_work(struct work_struct *work)
{
	struct max77660_haptic *chip =
		container_of(work, struct max77660_haptic, work);
	unsigned int approved;
	int ret;

	if (chip->level) {
		/* Request E-state before operating */
		if (chip->haptic_edp_client) {
			ret = edp_update_client_request(chip->haptic_edp_client,
					MAX77660_HAPTIC_EDP_HIGH, &approved);
			if (ret || approved != MAX77660_HAPTIC_EDP_HIGH) {
				dev_err(chip->dev,
					"E state high transition failed, error=%d, approved=%d\n",
					ret, approved);
//				haptic_enable_processing = 0;		//Ivan
				mutex_unlock(&chip->enable_lock);
				return;
			}
		}
		ret = max77660_haptic_set_duty_cycle(chip);
		if (ret) {
			dev_err(chip->dev, "set_pwm_cycle failed\n");
//			haptic_enable_processing = 0;			//Ivan
			mutex_unlock(&chip->enable_lock);
			return;
		}

		max77660_haptic_enable(chip, true);
		mutex_unlock(&chip->enable_lock);		
	} else {
		/* Disable device before releasing E-state request */
		max77660_haptic_enable(chip, false);
		if (chip->haptic_edp_client) {
			ret = edp_update_client_request(chip->haptic_edp_client,
					MAX77660_HAPTIC_EDP_LOW, NULL);
			if (ret) {
				dev_err(chip->dev,
					"E state low transition failed, error=%d\n",
					ret);
				mutex_unlock(&chip->enable_lock);				
				return;
			}
		}
		mutex_unlock(&chip->enable_lock);
	}
}
static int tegra_aic326x_event_int_spk(struct snd_soc_dapm_widget *w,
					struct snd_kcontrol *k, int event)
{
	struct snd_soc_dapm_context *dapm = w->dapm;
	struct snd_soc_card *card = dapm->card;
	struct snd_soc_codec *codec = card->rtd[DAI_LINK_HIFI].codec;
	struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
	struct tegra_asoc_platform_data *pdata = machine->pdata;
	unsigned int approved;
	int ret;

	if (machine->spk_edp_client == NULL)
		goto err_null_spk_edp_client;

	if (SND_SOC_DAPM_EVENT_ON(event)) {
		ret = edp_update_client_request(
				machine->spk_edp_client,
				TEGRA_SPK_EDP_NEG_1, &approved);
		if (ret || approved != TEGRA_SPK_EDP_NEG_1) {
			/*  set speaker amplifier voulme to 6 dB, E0 state */
			snd_soc_write(codec, AIC3262_SPK_AMP_CNTL_R4, 0x11);
		} else {
			/*  set speaker amplifier voulme to 18 dB, E-1 state */
			snd_soc_write(codec, AIC3262_SPK_AMP_CNTL_R4, 0x33);
		}
	} else {
		ret = edp_update_client_request(
					machine->spk_edp_client,
					TEGRA_SPK_EDP_1, NULL);
		if (ret) {
			dev_err(card->dev,
				"E+1 state transition failed\n");
		}
	}
err_null_spk_edp_client:
	if (!(machine->gpio_requested & GPIO_SPKR_EN))
		return 0;

	gpio_set_value_cansleep(pdata->gpio_spkr_en,
				!!SND_SOC_DAPM_EVENT_ON(event));

	return 0;
}
示例#3
0
static int pwm_backlight_update_status(struct backlight_device *bl)
{
	struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
	int brightness = bl->props.brightness;
	int max = bl->props.max_brightness;
	int approved;
	int edp_state;
	int i;
	int ret;

	if (pb->display_init && !pb->display_init(pb->dev))
		brightness = 0;

	if (bl->props.power != FB_BLANK_UNBLANK)
		brightness = 0;

	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
		brightness = 0;

	if (pb->notify)
		brightness = pb->notify(pb->dev, brightness);

	if (pb->tegra_pwm_bl_edp_client) {
		for (i = 0; i < TEGRA_PWM_BL_EDP_NUM_STATES; i++) {
			if (brightness >= pb->edp_brightness_states[i])
				break;
		}
		edp_state = i;
		ret = edp_update_client_request(pb->tegra_pwm_bl_edp_client,
					edp_state, &approved);
		if (ret || approved != edp_state)
			dev_err(&bl->dev, "E state transition failed\n");
	}

	if (brightness == 0) {
		gpio_set_value(DSI_PANEL_BL_EN, 0);

		pwm_config(pb->pwm, 0, pb->period);
		pwm_disable(pb->pwm);
	} else {
		brightness = pb->lth_brightness +
			(brightness * (pb->period - pb->lth_brightness) / max);
		pwm_config(pb->pwm, brightness, pb->period);
		pwm_enable(pb->pwm);

		msleep(10);
		gpio_set_value(DSI_PANEL_BL_EN, 1);
	}

	if (pb->notify_after)
		pb->notify_after(pb->dev, brightness);

	return 0;
}
static void max77665_haptic_play_effect_work(struct work_struct *work)
{
	struct max77665_haptic *chip =
		container_of(work, struct max77665_haptic, work);
	unsigned int approved;
	int ret;

	if (chip->level) {
		ret = max77665_haptic_set_duty_cycle(chip);
		if (ret) {
			dev_err(chip->dev, "set_pwm_cycle failed\n");
			return;
		}

		if (chip->haptic_edp_client) {
			ret = edp_update_client_request(chip->haptic_edp_client,
					MAX77665_HAPTIC_EDP_HIGH, &approved);
			if (ret || approved != MAX77665_HAPTIC_EDP_HIGH) {
				dev_err(chip->dev,
					"E state transition failed\n");
				return;
			}
		}
		max77665_haptic_enable(chip, true);
	} else {
		if (chip->haptic_edp_client) {
			ret = edp_update_client_request(chip->haptic_edp_client,
					MAX77665_HAPTIC_EDP_LOW, NULL);
			if (ret) {
				dev_err(chip->dev,
					"E state transition failed\n");
				return;
			}
		}
		max77665_haptic_enable(chip, false);
	}
}
static int max77665_haptic_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct max77665_haptic *chip = platform_get_drvdata(pdev);
	int ret;

	if (chip->haptic_edp_client) {
		ret = edp_update_client_request(chip->haptic_edp_client,
				MAX77665_HAPTIC_EDP_LOW, NULL);
		if (ret) {
			dev_err(chip->dev,
				"E state transition failed\n");
			return ret;
		}
	}
	max77665_haptic_enable(chip, false);

	return 0;
}
static int bbc_edp_request_unlocked(struct device *dev, u32 mode, u32 state,
				u32 threshold)
{
	int ret;
	struct edp_client *c;
	struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);

	dev_dbg(dev, "bbc edp request - state: %u threshold: %u mode: %u\n",
			state, threshold, mode);

	if (!bbc->edp_client_registered)
		return -EINVAL;

	if (mode)
		atomic_set(&bbc->mode, mode);

	if (state != bbc->state) {
		c = &bbc->modem_edp_client;
		if (state >= c->num_states)
			return -EINVAL;

		ret = edp_update_client_request(c, state, NULL);
		if (ret) {
			dev_err(dev, "state update to %u failed\n", state);
			return ret;
		}
		bbc->state = state;
	}

	if (threshold != bbc->threshold) {
		ret = edp_update_loan_threshold(&bbc->modem_edp_client,
						threshold);
		if (ret) {
			dev_err(dev, "threshold update to %u failed\n",
				threshold);
			return ret;
		}
		bbc->threshold = threshold;
	}

	return 0;
}
示例#7
0
static void depl_update(struct work_struct *work)
{
	struct depl_driver *drv;
	struct edp_client *c;
	unsigned int depl;
	unsigned int i;

	drv = container_of(work, struct depl_driver, work.work);
	c = &drv->client;
	depl = depl_calc(drv);

	i = c->num_states - 1;
	while (i && c->states[i] < depl)
		i--;

	edp_update_client_request(c, i, NULL);

	schedule_delayed_work(to_delayed_work(work),
			msecs_to_jiffies(DEPL_INTERVAL));
}
static int max77660_haptic_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct max77660_haptic *chip = platform_get_drvdata(pdev);
	int ret;

	/* Disable device before releasing E-state request */
//Ivan added
//	cancel_delayed_work(&chip->work);
	max77660_haptic_enable(chip, false);
	if (chip->haptic_edp_client) {
		ret = edp_update_client_request(chip->haptic_edp_client,
				MAX77660_HAPTIC_EDP_LOW, NULL);
		if (ret) {
			dev_err(chip->dev,
				"E state low transition failed in suspend\n");
			return ret;
		}
	}

	return 0;
}
static int __devinit max77665_haptic_probe(struct platform_device *pdev)
{
	struct max77665_haptic_platform_data *haptic_pdata =
					pdev->dev.platform_data;
	struct max77665_haptic *chip;
	struct edp_manager *battery_manager = NULL;
	struct input_dev *input_dev;
	int ret;

	if (!haptic_pdata) {
		dev_err(&pdev->dev, "no haptic platform data\n");
		return -EINVAL;
	}

	chip = devm_kzalloc(&pdev->dev, sizeof(struct max77665_haptic),
							GFP_KERNEL);
	if (!chip) {
		dev_err(&pdev->dev, "unable to allocate memory\n");
		return -ENOMEM;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&pdev->dev,
			"unable to allocate memory for input dev\n");
		ret = -ENOMEM;
		goto err_input_alloc;
	}

	chip->dev = &pdev->dev;
	chip->input_dev = input_dev;
	chip->pwm_period = haptic_pdata->pwm_period;
	chip->type = haptic_pdata->type;
	chip->mode = haptic_pdata->mode;
	chip->pwm_divisor = haptic_pdata->pwm_divisor;

	if (chip->mode == MAX77665_INTERNAL_MODE) {
		chip->internal_mode_pattern =
				haptic_pdata->internal_mode_pattern;
		chip->pattern_cycle = haptic_pdata->pattern_cycle;
		chip->pattern_signal_period =
				haptic_pdata->pattern_signal_period;
		chip->feedback_duty_cycle =
				haptic_pdata->feedback_duty_cycle;
		chip->invert = haptic_pdata->invert;
		chip->cont_mode = haptic_pdata->cont_mode;
		chip->motor_startup_val = haptic_pdata->motor_startup_val;
		chip->scf_val = haptic_pdata->scf_val;
	}

	if (chip->mode == MAX77665_EXTERNAL_MODE) {
		chip->pwm = pwm_request(haptic_pdata->pwm_channel_id,
					"max-vbrtr");
		if (IS_ERR(chip->pwm)) {
			dev_err(&pdev->dev,
				"unable to request PWM for haptic\n");
			ret = PTR_ERR(chip->pwm);
			goto err_pwm;
		}
	}

	chip->regulator = regulator_get(&pdev->dev, "vdd_vbrtr");
	if (IS_ERR(chip->regulator)) {
		dev_err(&pdev->dev, "unable to get regulator\n");
		ret = PTR_ERR(chip->regulator);
		goto err_regulator;
	}

	if (haptic_pdata->edp_states == NULL)
		goto register_input;

	chip->haptic_edp_client = devm_kzalloc(&pdev->dev,
				sizeof(struct edp_client), GFP_KERNEL);
	if (IS_ERR_OR_NULL(chip->haptic_edp_client)) {
		dev_err(&pdev->dev, "could not allocate edp client\n");
		goto register_input;
	}

	chip->haptic_edp_client->name[EDP_NAME_LEN - 1] = '\0';
	strncpy(chip->haptic_edp_client->name, "vibrator", EDP_NAME_LEN - 1);
	chip->haptic_edp_client->states = haptic_pdata->edp_states;
	chip->haptic_edp_client->num_states = MAX77665_HAPTIC_EDP_NUM_STATES;
	chip->haptic_edp_client->e0_index = MAX77665_HAPTIC_EDP_LOW;
	chip->haptic_edp_client->priority = EDP_MAX_PRIO + 2;
	chip->haptic_edp_client->throttle = max77665_haptic_throttle;
	chip->haptic_edp_client->private_data = chip;

	battery_manager = edp_get_manager("battery");
	if (!battery_manager) {
		dev_err(&pdev->dev, "unable to get edp manager\n");
	} else {
		ret = edp_register_client(battery_manager,
					chip->haptic_edp_client);
		if (ret) {
			dev_err(&pdev->dev, "unable to register edp client\n");
		} else {
			ret = edp_update_client_request(chip->haptic_edp_client,
				MAX77665_HAPTIC_EDP_LOW, NULL);
			if (ret) {
				dev_err(&pdev->dev,
					"unable to set E0 EDP state\n");
				edp_unregister_client(chip->haptic_edp_client);
			} else {
				goto register_input;
			}
		}
	}

	devm_kfree(&pdev->dev, chip->haptic_edp_client);
	chip->haptic_edp_client = NULL;

register_input:
	dev_set_drvdata(&pdev->dev, chip);
	input_dev->name = "max77665-haptic";
	input_dev->id.version = 1;
	input_dev->dev.parent = &pdev->dev;
	input_set_drvdata(input_dev, chip);
	input_set_capability(input_dev, EV_FF, FF_RUMBLE);

	ret = input_ff_create_memless(input_dev, NULL,
				max77665_haptic_play_effect);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to create FF device(ret : %d)\n", ret);
		goto err_ff_memless;
	}
	INIT_WORK(&chip->work,
			max77665_haptic_play_effect_work);

	ret = input_register_device(input_dev);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to register input device(ret : %d)\n", ret);
		goto err_input_register;
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &max77665_haptics_attr_group);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"unable to create sysfs %d\n", ret);
	}

	return 0;

err_input_register:
	destroy_work_on_stack(&chip->work);
	input_ff_destroy(input_dev);
err_ff_memless:
	regulator_put(chip->regulator);
err_regulator:
	if (chip->mode == MAX77665_EXTERNAL_MODE)
		pwm_free(chip->pwm);
err_pwm:
	input_free_device(input_dev);
err_input_alloc:
	kfree(chip);

	return ret;
}
示例#10
0
static int pwm_backlight_probe(struct platform_device *pdev)
{
	struct backlight_properties props;
	struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
	struct backlight_device *bl;
	struct pwm_bl_data *pb;
	struct edp_manager *battery_manager = NULL;
	int ret;

	if (!data) {
		dev_err(&pdev->dev, "failed to find platform data\n");
		return -EINVAL;
	}

	if (data->init) {
		ret = data->init(&pdev->dev);
		if (ret < 0)
			return ret;
	}

	pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
	if (!pb) {
		dev_err(&pdev->dev, "no memory for state\n");
		ret = -ENOMEM;
		goto err_alloc;
	}

	pb->period = data->pwm_period_ns;
	pb->notify = data->notify;
	pb->notify_after = data->notify_after;
	pb->check_fb = data->check_fb;
	pb->lth_brightness = data->lth_brightness *
		(data->pwm_period_ns / data->max_brightness);
	pb->dev = &pdev->dev;
	pb->display_init = data->init;
	pb->pwm_gpio = data->pwm_gpio;
	pb->edp_brightness_states = data->edp_brightness;

	pb->pwm = pwm_request(data->pwm_id, "backlight");
	if (IS_ERR(pb->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM for backlight\n");
		ret = PTR_ERR(pb->pwm);
		goto err_alloc;
	} else
		dev_dbg(&pdev->dev, "got pwm for backlight\n");

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = data->max_brightness;

	if (gpio_is_valid(pb->pwm_gpio)) {
		ret = gpio_request(pb->pwm_gpio, "disp_bl");
		if (ret)
			dev_err(&pdev->dev, "backlight gpio request failed\n");
	}

	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
				       &pwm_backlight_ops, &props);
	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "failed to register backlight\n");
		ret = PTR_ERR(bl);
		goto err_bl;
	}

	pb->tegra_pwm_bl_edp_client = devm_kzalloc(&pdev->dev,
			sizeof(struct edp_client), GFP_KERNEL);
	if (IS_ERR_OR_NULL(pb->tegra_pwm_bl_edp_client)) {
		dev_err(&pdev->dev, "could not allocate edp client\n");
		return PTR_ERR(pb->tegra_pwm_bl_edp_client);
	}
	strncpy(pb->tegra_pwm_bl_edp_client->name,
			"backlight", EDP_NAME_LEN - 1);
	pb->tegra_pwm_bl_edp_client->name[EDP_NAME_LEN - 1] = '\0';
	pb->tegra_pwm_bl_edp_client->states = data->edp_states;
	pb->tegra_pwm_bl_edp_client->num_states = TEGRA_PWM_BL_EDP_NUM_STATES;
	pb->tegra_pwm_bl_edp_client->e0_index = TEGRA_PWM_BL_EDP_ZERO;
	pb->tegra_pwm_bl_edp_client->private_data = bl;
	pb->tegra_pwm_bl_edp_client->priority = EDP_MAX_PRIO + 2;
	pb->tegra_pwm_bl_edp_client->throttle = pwm_backlight_edpcb;
	pb->tegra_pwm_bl_edp_client->notify_promotion = pwm_backlight_edpcb;

	battery_manager = edp_get_manager("battery");
	if (!battery_manager) {
		dev_err(&pdev->dev, "unable to get edp manager\n");
	} else {
		ret = edp_register_client(battery_manager,
					pb->tegra_pwm_bl_edp_client);
		if (ret) {
			dev_err(&pdev->dev, "unable to register edp client\n");
		} else {
			ret = edp_update_client_request(
					pb->tegra_pwm_bl_edp_client,
						TEGRA_PWM_BL_EDP_ZERO, NULL);
			if (ret) {
				dev_err(&pdev->dev,
					"unable to set E0 EDP state\n");
				edp_unregister_client(
					pb->tegra_pwm_bl_edp_client);
			} else {
				goto edp_success;
			}
		}
	}

	devm_kfree(&pdev->dev, pb->tegra_pwm_bl_edp_client);
	pb->tegra_pwm_bl_edp_client = NULL;

edp_success:

	bl->props.brightness = data->dft_brightness;
	backlight_update_status(bl);

	if (gpio_is_valid(pb->pwm_gpio))
		gpio_free(pb->pwm_gpio);

	platform_set_drvdata(pdev, bl);
	return 0;

err_bl:
	pwm_free(pb->pwm);
err_alloc:
	if (data->exit)
		data->exit(&pdev->dev);
	return ret;
}
static int tegra_bbc_proxy_probe(struct platform_device *pdev)
{
	struct tegra_bbc_proxy_platform_data *pdata = pdev->dev.platform_data;
	struct tegra_bbc_proxy *bbc;
	struct edp_manager *mgr;
	struct device_attribute **attrs;
	struct device_attribute *attr;
	int ret = 0;

	/* check for platform data */
	if (!pdata) {
		dev_err(&pdev->dev, "platform data not available\n");
		return -ENODEV;
	}

	bbc = kzalloc(sizeof(struct tegra_bbc_proxy), GFP_KERNEL);
	if (!bbc) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	if (pdata->modem_boot_edp_client && pdata->edp_manager_name) {
		mutex_init(&bbc->edp_lock);

		/* register bbc boot client */
		bbc->edp_manager_name = pdata->edp_manager_name;
		mgr = edp_get_manager(pdata->edp_manager_name);
		if (!mgr) {
			dev_err(&pdev->dev, "can't get edp manager\n");
			/* goto error; */
			goto bypass_edp;
		}

		bbc->modem_boot_edp_client = pdata->modem_boot_edp_client;
		ret = edp_register_client(mgr, bbc->modem_boot_edp_client);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to register bbc boot edp client\n");
			/* goto error; */
			goto bypass_edp;
		}

		/* request E0 */
		ret = edp_update_client_request(bbc->modem_boot_edp_client,
						0, NULL);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to set e0 state\n");
			/* goto edp_req_error; */
			edp_unregister_client(bbc->modem_boot_edp_client);
			bbc->modem_boot_edp_client = NULL;
			goto bypass_edp;
		}

		bbc->edp_boot_client_registered = 1;

		attrs = edp_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				//goto edp_req_error;

				edp_unregister_client(bbc->modem_boot_edp_client);
				bbc->modem_boot_edp_client = NULL;
				bbc->edp_boot_client_registered = 0;
				goto bypass_edp;
			}
		}

		bbc->edp_initialized = 1;
		bbc->ap_name = pdata->ap_name;
	}

bypass_edp:
	mutex_init(&bbc->iso_lock);

	bbc->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_BBC_0,
		BBC_ISO_BOOT_BW, NULL, NULL);
	if (!bbc->isomgr_handle)
		goto iso_error;

	/* statically margin for bbc bw */
	ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
		BBC_ISO_MARGIN_BW, true);
	if (ret)
		dev_err(&pdev->dev, "can't margin for bbc bw\n");
	else
		bbc->margin = BBC_ISO_MARGIN_BW;

	/* thermal zones from bbc */
	tegra_bbc_thermal_init();

	/* power values to bbc */
	tegra_bbc_power_init(pdev);

	attrs = mc_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto mc_error;
		}
	}

	bbc->sim0 = regulator_get(&pdev->dev, "vddio_sim0");
	if (IS_ERR(bbc->sim0)) {
		dev_err(&pdev->dev, "vddio_sim0 regulator get failed\n");
		bbc->sim0 = NULL;
		goto sim_error;
	}

	bbc->sim1 = regulator_get(&pdev->dev, "vddio_sim1");
	if (IS_ERR(bbc->sim1)) {
		dev_err(&pdev->dev, "vddio_sim1 regulator get failed\n");
		bbc->sim1 = NULL;
		goto sim_error;
	}

	attrs = sim_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto sim_error;
		}
	}

	bbc->rf1v7 = regulator_get(&pdev->dev, "vdd_1v7_rf");
	if (IS_ERR(bbc->rf1v7)) {
		dev_info(&pdev->dev,
			 "vdd_1v7_rf regulator not available\n");
		bbc->rf1v7 = NULL;
	}

	bbc->rf2v65 = regulator_get(&pdev->dev, "vdd_2v65_rf");
	if (IS_ERR(bbc->rf2v65)) {
		dev_info(&pdev->dev,
			 "vdd_2v65_rf regulator not available\n");
		bbc->rf2v65 = NULL;
	}

	if (bbc->rf1v7 && bbc->rf2v65) {
		attrs = rf_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				goto rf_error;
			}
		}
	}

	bbc->bb_efuse = regulator_get(&pdev->dev, "vpp_bb_fuse");
	if (IS_ERR(bbc->bb_efuse)) {
		dev_info(&pdev->dev,
			 "vpp_bb_fuse regulator not available\n");
		bbc->bb_efuse = NULL;
	}

	atomic_set(&bbc->mode, 0);
	ret = device_create_file(&pdev->dev, &mode_attr);
	if (ret) {
		dev_err(&pdev->dev, "can't create sysfs file\n");
		goto mode_error;
	}

	/* set to -1 to ensure the mode gets programmed the first time */
	bbc->fpwm = -1;

	dev_set_drvdata(&pdev->dev, bbc);

	return 0;

mode_error:
	regulator_put(bbc->bb_efuse);
	attrs = rf_attributes;
	while ((attr = *attrs++))
		device_remove_file(&pdev->dev, attr);

rf_error:
	regulator_put(bbc->rf1v7);
	regulator_put(bbc->rf2v65);
sim_error:
	regulator_put(bbc->sim0);
	regulator_put(bbc->sim1);

	attrs = mc_attributes;
	while ((attr = *attrs++))
		device_remove_file(&pdev->dev, attr);

mc_error:
	tegra_isomgr_unregister(bbc->isomgr_handle);

iso_error:
	if (bbc->edp_initialized) {
		attrs = edp_attributes;
		while ((attr = *attrs++))
			device_remove_file(&pdev->dev, attr);
	}
#if 0
edp_req_error:
	if (bbc->edp_boot_client_registered)
		edp_unregister_client(bbc->modem_boot_edp_client);

error:
	kfree(bbc);
#endif
	return ret;
}
int tegra_bbc_proxy_edp_register(struct device *dev, u32 num_states,
				u32 *states)
{
	struct edp_manager *mgr;
	struct edp_client *ap;
	int ret;
	int i;
	struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);

	mutex_lock(&bbc->edp_lock);

	/* client should only be registered once per modem boot */
	if (bbc->edp_client_registered) {
		dev_err(dev, "bbc edp client already registered\n");
		ret = -EBUSY;
		goto done;
	}

	memset(bbc->modem_edp_states, 0, sizeof(bbc->modem_edp_states));
	memset(&bbc->modem_edp_client, 0, sizeof(bbc->modem_edp_client));

	/* retrieve max current for supported states */
	for (i = 0; i < num_states; i++) {
		bbc->modem_edp_states[i] = *states;
		states++;
	}

	strncpy(bbc->modem_edp_client.name, "bbc", EDP_NAME_LEN);
	bbc->modem_edp_client.name[EDP_NAME_LEN - 1] = '\0';
	bbc->modem_edp_client.states = bbc->modem_edp_states;
	bbc->modem_edp_client.num_states = num_states;
	bbc->modem_edp_client.e0_index = BBC_EDP_E0_INDEX;
	bbc->modem_edp_client.max_borrowers = 1;
	bbc->modem_edp_client.priority = EDP_MAX_PRIO;

	mgr = edp_get_manager(bbc->edp_manager_name);
	if (!mgr) {
		dev_err(dev, "can't get edp manager\n");
		ret = -EINVAL;
		goto done;
	}

	/* unregister modem_boot_client */
	ret = edp_unregister_client(bbc->modem_boot_edp_client);
	if (ret) {
		dev_err(dev, "unable to register bbc boot edp client\n");
		goto done;
	}

	bbc->edp_boot_client_registered = 0;

	/* register modem client */
	ret = edp_register_client(mgr, &bbc->modem_edp_client);
	if (ret) {
		dev_err(dev, "unable to register bbc edp client\n");
		goto done;
	}

	bbc->edp_client_registered = 1;

	ret = edp_update_client_request(&bbc->modem_edp_client,
					BBC_EDP_E0_INDEX, NULL);
	if (ret) {
		dev_err(dev, "initial state update failed\n");
		goto done;
	}

	bbc->state = 0;

	ap = edp_get_client(bbc->ap_name);
	if (!ap) {
		dev_err(dev, "can't get ap client\n");
		goto done;
	}

	ret = edp_register_loan(&bbc->modem_edp_client, ap);
	if (ret && ret != -EEXIST) {
		dev_err(dev, "unable to register bbc loan to ap\n");
		goto done;
	}

	dev_dbg(dev, "bbc edp client registered\n");
done:
	mutex_unlock(&bbc->edp_lock);
	return ret;
}
static __devinit int tegra_aic326x_driver_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_tegra_aic326x;
	struct snd_soc_codec *codec;
	struct tegra_aic326x *machine;
	struct tegra_asoc_platform_data *pdata;
	struct edp_manager *battery_manager = NULL;
	int ret;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	int i;
#endif
	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		return -EINVAL;
	}

	machine = kzalloc(sizeof(struct tegra_aic326x), GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate tegra_aic326x struct\n");
		return -ENOMEM;
	}

	machine->pdata = pdata;

	ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev, card);
	if (ret)
		goto err_free_machine;

	machine->dmic_reg = regulator_get(&pdev->dev, "vdd_mic");
	if (IS_ERR(machine->dmic_reg)) {
		dev_info(&pdev->dev, "No digital mic regulator found\n");
		machine->dmic_reg = 0;
	}

	machine->dmic_1v8_reg = regulator_get(&pdev->dev, "vdd_1v8_mic");
	if (IS_ERR(machine->dmic_1v8_reg)) {
		dev_info(&pdev->dev, "No digital mic regulator found\n");
		machine->dmic_1v8_reg = 0;
	}

	machine->hmic_reg = regulator_get(&pdev->dev, "mic_ventral");
	if (IS_ERR(machine->hmic_reg)) {
		dev_info(&pdev->dev, "No headset mic regulator found\n");
		machine->hmic_reg = 0;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);

#ifdef CONFIG_SWITCH
	/* Add h2w switch class support */
	ret = tegra_asoc_switch_register(&aic326x_wired_switch_dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "not able to register switch device %d\n",
			ret);
		goto err_fini_utils;
	}
#endif

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	for (i = 0; i < NUM_I2S_DEVICES ; i++) {
		machine->codec_info[i].i2s_id =
			pdata->i2s_param[i].audio_port_id;
		machine->codec_info[i].bitsize =
			pdata->i2s_param[i].sample_size;
		machine->codec_info[i].is_i2smaster =
			pdata->i2s_param[i].is_i2s_master;
		machine->codec_info[i].rate =
			pdata->i2s_param[i].rate;
		machine->codec_info[i].channels =
			pdata->i2s_param[i].channels;
		machine->codec_info[i].i2s_mode =
			pdata->i2s_param[i].i2s_mode;
		machine->codec_info[i].bit_clk =
			pdata->i2s_param[i].bit_clk;

	}

	tegra_aic326x_dai[DAI_LINK_HIFI].cpu_dai_name =
	tegra_i2s_dai_name[machine->codec_info[HIFI_CODEC].i2s_id];

	tegra_aic326x_dai[DAI_LINK_BTSCO].cpu_dai_name =
	tegra_i2s_dai_name[machine->codec_info[BT_SCO].i2s_id];
#endif

	if (machine_is_tegra_enterprise()) {
		tegra_aic326x_dai[DAI_LINK_HIFI].codec_name =
						"tlv320aic3262-codec";
		tegra_aic326x_dai[DAI_LINK_VOICE_CALL].codec_name =
						"tlv320aic3262-codec";
		tegra_aic326x_dai[DAI_LINK_VOICE_CALL].codec_dai_name =
						"aic326x-asi1";
	}

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_switch_unregister;
	}

	if (!card->instantiated) {
		dev_err(&pdev->dev, "No TI AIC3262 codec\n");
		goto err_unregister_card;
	}

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	ret = tegra_asoc_utils_set_parent(&machine->util_data,
				pdata->i2s_param[HIFI_CODEC].is_i2s_master);
	if (ret) {
		dev_err(&pdev->dev, "tegra_asoc_utils_set_parent failed (%d)\n",
			ret);
		goto err_unregister_card;
	}
#endif

	if (pdata->edp_states == NULL)
		return 0;

	machine->spk_edp_client = devm_kzalloc(&pdev->dev,
					sizeof(struct edp_client),
					GFP_KERNEL);
	if (IS_ERR_OR_NULL(machine->spk_edp_client)) {
		dev_err(&pdev->dev, "could not allocate edp client\n");
		return 0;
	}
	machine->spk_edp_client->name[EDP_NAME_LEN - 1] = '\0';
	strncpy(machine->spk_edp_client->name, "speaker", EDP_NAME_LEN - 1);
	machine->spk_edp_client->states = pdata->edp_states;
	machine->spk_edp_client->num_states = TEGRA_SPK_EDP_NUM_STATES;
	machine->spk_edp_client->e0_index = TEGRA_SPK_EDP_ZERO;
	machine->spk_edp_client->priority = EDP_MAX_PRIO + 2;
	machine->spk_edp_client->throttle = tegra_speaker_throttle;
	machine->spk_edp_client->private_data = machine;

	battery_manager = edp_get_manager("battery");
	if (!battery_manager) {
		dev_err(&pdev->dev, "unable to get edp manager\n");
	} else {
		/* register speaker edp client */
		ret = edp_register_client(battery_manager,
					machine->spk_edp_client);
		if (ret) {
			dev_err(&pdev->dev, "unable to register edp client\n");
			devm_kfree(&pdev->dev, machine->spk_edp_client);
			machine->spk_edp_client = NULL;
			return 0;
		}
		codec = card->rtd[DAI_LINK_HIFI].codec;
		/*  set speaker amplifier volume to 6 dB , E0 state*/
		snd_soc_write(codec, AIC3262_SPK_AMP_CNTL_R4, 0x11);
		/* request E1 */
		ret = edp_update_client_request(machine->spk_edp_client,
				TEGRA_SPK_EDP_1, NULL);
		if (ret) {
			dev_err(&pdev->dev,
					"unable to set E1 EDP state\n");
			edp_unregister_client(machine->spk_edp_client);
			devm_kfree(&pdev->dev, machine->spk_edp_client);
			machine->spk_edp_client = NULL;
		}
	}
	return 0;

err_unregister_card:
	snd_soc_unregister_card(card);
err_switch_unregister:
#ifdef CONFIG_SWITCH
	tegra_asoc_switch_unregister(&aic326x_wired_switch_dev);
#endif
err_fini_utils:
	tegra_asoc_utils_fini(&machine->util_data);
err_free_machine:
	kfree(machine);
	return ret;
}
示例#14
0
static int tegra_bbc_proxy_probe(struct platform_device *pdev)
{
	struct tegra_bbc_proxy_platform_data *pdata = pdev->dev.platform_data;
	struct tegra_bbc_proxy *bbc;
	struct edp_manager *mgr;
	struct device_attribute **attrs;
	struct device_attribute *attr;
	int ret = 0;

	/* check for platform data */
	if (!pdata) {
		dev_err(&pdev->dev, "platform data not available\n");
		return -ENODEV;
	}

	bbc = kzalloc(sizeof(struct tegra_bbc_proxy), GFP_KERNEL);
	if (!bbc) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	if (pdata->modem_boot_edp_client && pdata->edp_manager_name) {
		mutex_init(&bbc->edp_lock);

		/* register bbc boot client */
		bbc->edp_manager_name = pdata->edp_manager_name;
		mgr = edp_get_manager(pdata->edp_manager_name);
		if (!mgr) {
			dev_err(&pdev->dev, "can't get edp manager\n");
			goto error;
		}

		bbc->modem_boot_edp_client = pdata->modem_boot_edp_client;
		ret = edp_register_client(mgr, bbc->modem_boot_edp_client);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to register bbc boot edp client\n");
			goto error;
		}

		/* request E0 */
		ret = edp_update_client_request(bbc->modem_boot_edp_client,
						0, NULL);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to set e0 state\n");
			goto edp_req_error;
		}

		bbc->edp_boot_client_registered = 1;

		bbc->i_breach_ppm = pdata->i_breach_ppm;
		bbc->i_thresh_3g_adjperiod = pdata->i_thresh_3g_adjperiod;
		bbc->i_thresh_lte_adjperiod = pdata->i_thresh_lte_adjperiod;

		attrs = edp_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				goto edp_req_error;
			}
		}

		bbc->edp_initialized = 1;
		bbc->ap_name = pdata->ap_name;
	}

	mutex_init(&bbc->iso_lock);

	bbc->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_BBC_0,
		MAX_ISO_BW_REQ, NULL, NULL);
	if (!bbc->isomgr_handle)
		goto iso_error;

	tegra_set_latency_allowance(TEGRA_LA_BBCLLR, 640);

	/* statically margin for bbc bw */
	ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
		MAX_ISO_BW_REQ, true);
	if (ret)
		dev_err(&pdev->dev, "can't margin for bbc bw\n");
	else
		bbc->margin = MAX_ISO_BW_REQ;

	/* thermal zones from bbc */
	tegra_bbc_thermal_init();

	attrs = mc_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto mc_error;
		}
	}

	bbc->sim0 = regulator_get(&pdev->dev, "vddio_sim0");
	if (IS_ERR(bbc->sim0)) {
		dev_err(&pdev->dev, "vddio_sim0 regulator get failed\n");
		bbc->sim0 = NULL;
		goto sim_error;
	}

	bbc->sim1 = regulator_get(&pdev->dev, "vddio_sim1");
	if (IS_ERR(bbc->sim1)) {
		dev_err(&pdev->dev, "vddio_sim1 regulator get failed\n");
		bbc->sim1 = NULL;
		goto sim_error;
	}

	attrs = sim_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto sim_error;
		}
	}

	bbc->rf1v7 = regulator_get(&pdev->dev, "vdd_1v7_rf");
	if (IS_ERR(bbc->rf1v7)) {
		dev_info(&pdev->dev,
			 "vdd_1v7_rf regulator not available\n");
		bbc->rf1v7 = NULL;
	}

	bbc->rf2v65 = regulator_get(&pdev->dev, "vdd_2v65_rf");
	if (IS_ERR(bbc->rf2v65)) {
		dev_info(&pdev->dev,
			 "vdd_2v65_rf regulator not available\n");
		bbc->rf2v65 = NULL;
	}

	if (bbc->rf1v7 && bbc->rf2v65) {
		attrs = rf_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				goto rf_error;
			}
		}
	}

	dev_set_drvdata(&pdev->dev, bbc);

	return 0;

rf_error:
	regulator_put(bbc->rf1v7);
	regulator_put(bbc->rf2v65);
sim_error:
	regulator_put(bbc->sim0);
	regulator_put(bbc->sim1);

	attrs = mc_attributes;
	while ((attr = *attrs++))
		device_remove_file(&pdev->dev, attr);

mc_error:
	tegra_isomgr_unregister(bbc->isomgr_handle);

iso_error:
	if (bbc->edp_initialized) {
		attrs = edp_attributes;
		while ((attr = *attrs++))
			device_remove_file(&pdev->dev, attr);
	}

edp_req_error:
	if (bbc->edp_boot_client_registered)
		edp_unregister_client(bbc->modem_boot_edp_client);

error:
	kfree(bbc);

	return ret;
}