Ejemplo n.º 1
0
static int instinctq_battery_probe(struct platform_device *pdev)
{
	struct s3c_adc_client	*client;
	struct instinctq_battery_pdata *pdata = pdev->dev.platform_data;
	struct instinctq_battery *bat;
	int ret, i, irq;

	/* Platform data is required */
	if (!pdata) {
		dev_err(&pdev->dev, "no platform data supplied\n");
		return -ENODEV;
	}

	/* Check GPIOs */
	if (!gpio_is_valid(pdata->gpio_pok)) {
		dev_err(&pdev->dev, "Invalid gpio pin for POK line\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_chg)) {
		dev_err(&pdev->dev, "Invalid gpio pin for CHG line\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_en)) {
		dev_err(&pdev->dev, "Invalid gpio pin for EN line\n");
		return -EINVAL;
	}

	if (!pdata->supply_detect_init) {
		dev_err(&pdev->dev, "Supply detection is required\n");
		return -EINVAL;
	}

	/* Register ADC client */
	client = s3c_adc_register(pdev, NULL, NULL, 0);
	if (IS_ERR(client)) {
		dev_err(&pdev->dev, "could not register adc\n");
		return PTR_ERR(client);
	}

	/* Allocate driver data */
	bat = kzalloc(sizeof(struct instinctq_battery), GFP_KERNEL);
	if (!bat) {
		dev_err(&pdev->dev, "could not allocate driver data\n");
		ret = -ENOMEM;
		goto err_free_adc;
	}

	/* Claim and setup GPIOs */
	ret = gpio_request(pdata->gpio_pok, dev_name(&pdev->dev));
	if (ret) {
		dev_err(&pdev->dev, "Failed to request POK pin: %d\n", ret);
		goto err_free;
	}

	ret = gpio_direction_input(pdata->gpio_pok);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set POK to input: %d\n", ret);
		goto err_gpio_pok_free;
	}

	ret = gpio_request(pdata->gpio_chg, dev_name(&pdev->dev));
	if (ret) {
		dev_err(&pdev->dev, "Failed to request CHG pin: %d\n", ret);
		goto err_gpio_pok_free;
	}

	ret = gpio_direction_input(pdata->gpio_chg);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set CHG to input: %d\n", ret);
		goto err_gpio_chg_free;
	}

	ret = gpio_request(pdata->gpio_en, dev_name(&pdev->dev));
	if (ret) {
		dev_err(&pdev->dev, "Failed to request EN pin: %d\n", ret);
		goto err_gpio_chg_free;
	}

	ret = gpio_direction_output(pdata->gpio_en, pdata->gpio_en_inverted);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set EN to output: %d\n", ret);
		goto err_gpio_en_free;
	}

	platform_set_drvdata(pdev, bat);

	bat->dev = &pdev->dev;
	bat->client = client;
	bat->pdata = pdata;
	bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
	bat->health = POWER_SUPPLY_HEALTH_GOOD;
	bat->supply = instinctq_BATTERY_NONE;
	bat->interval = BAT_POLL_INTERVAL;
	bat->calibration = pdata->calibration;

	ret = create_lookup_table(pdata->percent_lut,
				pdata->percent_lut_cnt, &bat->percent_lookup);
	if (ret) {
		dev_err(&pdev->dev, "could not get create percentage lookup table");
		goto err_gpio_en_free;
	}

	ret = create_lookup_table(pdata->volt_lut,
				pdata->volt_lut_cnt, &bat->volt_lookup);
	if (ret) {
		dev_err(&pdev->dev, "could not get create voltage lookup table");
		goto err_percent_free;
	}

	ret = create_lookup_table(pdata->temp_lut,
				pdata->temp_lut_cnt, &bat->temp_lookup);
	if (ret) {
		dev_err(&pdev->dev, "could not get create temperature lookup table");
		goto err_volt_free;
	}

	INIT_WORK(&bat->work, instinctq_battery_work);
	INIT_DELAYED_WORK(&bat->poll_work, instinctq_battery_poll);
	mutex_init(&bat->mutex);
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_init(&bat->wakelock, WAKE_LOCK_SUSPEND, "battery");
	wake_lock_init(&bat->chg_wakelock, WAKE_LOCK_SUSPEND, "charger");
	wake_lock_init(&bat->fault_wakelock,
					WAKE_LOCK_SUSPEND, "battery fault");
	wake_lock_init(&bat->suspend_lock, WAKE_LOCK_SUSPEND, "suspend_lock");
#endif
#ifdef CONFIG_RTC_INTF_ALARM
	alarm_init(&bat->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
							instinctq_battery_alarm);
#endif
	/* Get some initial data for averaging */
	for (i = 0; i < NUM_SAMPLES; ++i) {
		int sample;
		/* Get a voltage sample from the ADC */
		sample = instinctq_battery_adc_read(bat->client, bat->pdata->volt_channel);
		if (sample < 0) {
			dev_warn(&pdev->dev, "Failed to get ADC sample.\n");
			continue;
		}
		sample += bat->compensation;
		bat->vol_adc = sample;
		/* Put the sample and get the new average */
		bat->volt_value = put_sample_get_avg(&bat->volt_avg, sample);
		/* Get a temperature sample from the ADC */
		sample = instinctq_battery_adc_read(bat->client, bat->pdata->temp_channel);
		if (sample < 0) {
			dev_warn(&pdev->dev, "Failed to get ADC sample.\n");
			continue;
		}
		bat->temp_adc = sample;
		/* Put the sample and get the new average */
		bat->temp_value = put_sample_get_avg(&bat->temp_avg, sample);
	}

	bat->percent_value = lookup_value(&bat->percent_lookup, bat->volt_value);
	bat->volt_value = lookup_value(&bat->volt_lookup, bat->volt_value);
	bat->temp_value = lookup_value(&bat->temp_lookup, bat->temp_value);
	bat->last_sample = ktime_get_boottime();

	/* Register the power supplies */
	for (i = 0; i < instinctq_BATTERY_NUM; ++i) {
		bat->psy[i] = instinctq_chg_templates[i];
		ret = power_supply_register(&pdev->dev, &bat->psy[i]);
		if (ret < 0) {
			dev_err(&pdev->dev,
				"Failed to register power supply %s (%d)\n",
							bat->psy[i].name, ret);
			break;
		}
	}

	/* Undo the loop on error */
	if (i-- != instinctq_BATTERY_NUM) {
		for (; i >= 0; --i)
			power_supply_unregister(&bat->psy[i]);
		goto err_temp_free;
	}
#ifdef CONFIG_HAS_WAKELOCK
	ret = device_create_file(bat->psy[instinctq_BATTERY_AC].dev,
							&dev_attr_suspend_lock);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"Failed to register device attribute.\n");
		goto err_psy_unreg;
	}
#endif
	/* Register the battery */
	bat->bat = instinctq_bat_template;
	ret = power_supply_register(&pdev->dev, &bat->bat);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"Failed to register battery power supply: %d\n", ret);
		goto err_attr_unreg;
	}

	for (i = 0; i < ARRAY_SIZE(battery_attrs); ++i) {
		ret = device_create_file(bat->bat.dev, battery_attrs[i]);
		if (ret < 0)
			break;
	}

	if (ret < 0) {
		for (; i >= 0; --i)
			device_remove_file(bat->bat.dev, battery_attrs[i]);
		goto err_bat_unreg;
	}

	bat->workqueue = create_freezable_workqueue(dev_name(&pdev->dev));
	if (!bat->workqueue) {
		dev_err(&pdev->dev, "Failed to create freezeable workqueue\n");
		ret = -ENOMEM;
		goto err_remove_bat_attr;
	}

	/* Claim IRQs */
	irq = gpio_to_irq(pdata->gpio_pok);
	if (irq <= 0) {
		dev_err(&pdev->dev, "POK irq invalid.\n");
		goto err_destroy_workqueue;
	}
	bat->irq_pok = irq;

	ret = request_irq(irq, instinctq_charger_irq,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				dev_name(&pdev->dev), bat);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request POK irq (%d)\n", ret);
		goto err_destroy_workqueue;
	}

	ret = request_irq(IRQ_BATF, instinctq_battery_fault_irq,
						0, dev_name(&pdev->dev), bat);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to request battery fault irq (%d)\n", ret);
		goto err_pok_irq_free;
	}

	enable_irq_wake(bat->irq_pok);

	instinctq_battery_set_fault_enable(1);

	/* Finish */
	dev_info(&pdev->dev, "successfully loaded\n");
	device_init_wakeup(&pdev->dev, 1);

	pdata->supply_detect_init(instinctq_battery_supply_notify);

	/* Schedule work to check current status */
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock(&bat->wakelock);
#endif
	queue_work(bat->workqueue, &bat->work);

	return 0;

err_pok_irq_free:
	free_irq(bat->irq_pok, bat);
err_destroy_workqueue:
	destroy_workqueue(bat->workqueue);
err_remove_bat_attr:
	for (i = 0; i < ARRAY_SIZE(battery_attrs); ++i)
		device_remove_file(bat->bat.dev, battery_attrs[i]);
err_bat_unreg:
	power_supply_unregister(&bat->bat);
err_attr_unreg:
#ifdef CONFIG_HAS_WAKELOCK
	device_remove_file(bat->psy[instinctq_BATTERY_AC].dev,
							&dev_attr_suspend_lock);
err_psy_unreg:
#endif
	for (i = 0; i < instinctq_BATTERY_NUM; ++i)
		power_supply_unregister(&bat->psy[i]);
err_temp_free:
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_destroy(&bat->wakelock);
	wake_lock_destroy(&bat->chg_wakelock);
	wake_lock_destroy(&bat->fault_wakelock);
	wake_lock_destroy(&bat->suspend_lock);
#endif
	kfree(bat->temp_lookup.table);
err_volt_free:
	kfree(bat->volt_lookup.table);
err_percent_free:
	kfree(bat->percent_lookup.table);
err_gpio_en_free:
	gpio_free(pdata->gpio_en);
err_gpio_chg_free:
	gpio_free(pdata->gpio_chg);
err_gpio_pok_free:
	gpio_free(pdata->gpio_pok);
err_free:
	kfree(bat);
err_free_adc:
	s3c_adc_release(client);
	return ret;
}
Ejemplo n.º 2
0
int main()
{
	int X_in,Y_in;
#ifdef DISPLAY_OUTPUT
	double F_res = (double)F_SAMPLE/N_POINT ;
#endif

	int fft_in[N_POINT];
	int fft_out[N_POINT];
	int ifft_out[N_POINT];

	int word_mag;
	int word_sign;
	int j,k;
	double scale;
#ifdef MEASURE_TIME
	struct timeval tv1,tv2;
#endif

	create_lookup_table();
	calculate_rotation_angle(F_SAMPLE,F_OUT,&word_mag,&word_sign,&scale);
	printf("Rotation Magnitude = 0x%x\nRotation sign = 0x%x\nScale factor = %lf\n",word_mag,word_sign,scale);

	X_in = 0x8000;
	printf("Amplitude = %d\n",X_in);
	Y_in = 0;

	for(j=0;j<9999;j++){
		cordic_rotate(word_mag,word_sign,scale,&X_in,&Y_in);
		fft_in[j&(N_POINT-1)]= X_in;
		if(((j%(N_POINT-1)) == 0) && (j>0)){
			printf("\n");
#ifdef MEASURE_TIME
			gettimeofday(&tv1,NULL);
#endif
			fft_Npt(fft_in,fft_outX,fft_outY,N_POINT);
			ifft_Npt(fft_outX,fft_outY,ifft_outX,ifft_outY,N_POINT);
			for(k=0;k<N_POINT;k=k+2){
				fft_out[k] = cordic_vector(fft_outX[k],fft_outY[k]);
				fft_out[k+1] = cordic_vector(fft_outX[k+1],fft_outY[k+1]);

				ifft_out[k] = ifft_outX[k];
				ifft_out[k+1] = ifft_outX[k+1];
			}
#ifdef MEASURE_TIME
			gettimeofday(&tv2,NULL);
			printf("Time1 = %ld.%ld sec\nTime1 = %ld.%ld sec\n",tv2.tv_sec,tv2.tv_usec,tv1.tv_sec,tv1.tv_usec);
			printf("Time taken = %ld usec\n",tv2.tv_usec-tv1.tv_usec);
#endif
#ifdef DISPLAY_OUTPUT
			for(k=0;k<N_POINT;k++){
				printf("%.8f\t%d\t%10d\n",((k*1.0)/F_SAMPLE),ifft_out[k],fft_in[k]);
			}
			for(k=0;k<N_POINT;k++){
				printf("%.2f\t%d\t%10d\n",k*F_res,fft_out[k],fft_in[k]);
			}
#endif
			printf("\n\n");
		}
	}

	return 0;
}