/* ------------------------------------------------------------------------ */ /* ADDRESS SYMBOL DATA Init R/W */ /* D7 D6 D5 D4 D3 D2 D1 D0 */ /* ------------------------------------------------------------------------ */ /* 0 PROX X X X X X X X VO H'00 R */ /* 1 GAIN X X X X LED0 X X X H'00 W */ /* 2 HYS HYSD HYSC1 HYSC0 X HYSF3 HYSF2 HYSF1 HYSF0 H'00 W */ /* 3 CYCLE X X CYCL2 CYCL1 CYCL0 OSC2 X X H'00 W */ /* 4 OPMOD X X X ASD X X VCON SSD H'00 W */ /* 6 CON X X X OCON1 OCON0 X X X H'00 W */ /* ------------------------------------------------------------------------ */ /* VO :Proximity sensing result(0: no detection, 1: detection) */ /* LED0 :Select switch for LED driver's On-registence(0:2x higher, 1:normal)*/ /* HYSD/HYSF :Adjusts the receiver sensitivity */ /* OSC :Select switch internal clocl frequency hoppling(0:effective) */ /* CYCL :Determine the detection cycle(typically 8ms, up to 128x) */ /* SSD :Software Shutdown function(0:shutdown, 1:operating) */ /* VCON :VOUT output method control(0:normal, 1:interrupt) */ /* ASD :Select switch for analog sleep function(0:ineffective, 1:effective)*/ /* OCON :Select switch for enabling/disabling VOUT (00:enable, 11:disable) */
err_retrig:
ret = regmap_write(gp2ap002->map, GP2AP002_CON,
GP2AP002_CON_OCON_ENABLE); if (ret)
dev_err(gp2ap002->dev, "error setting up VOUT control\n");
staticint gp2ap002_init(struct gp2ap002 *gp2ap002)
{ int ret;
/* Set up the IR LED resistance */
ret = regmap_write(gp2ap002->map, GP2AP002_GAIN,
GP2AP002_GAIN_LED_NORMAL); if (ret) {
dev_err(gp2ap002->dev, "error setting up LED gain\n"); return ret;
}
ret = regmap_write(gp2ap002->map, GP2AP002_HYS, gp2ap002->hys_far); if (ret) {
dev_err(gp2ap002->dev, "error setting up proximity hysteresis\n"); return ret;
}
/* Disable internal frequency hopping */
ret = regmap_write(gp2ap002->map, GP2AP002_CYCLE,
GP2AP002_CYCLE_OSC_INEFFECTIVE); if (ret) {
dev_err(gp2ap002->dev, "error setting up internal frequency hopping\n"); return ret;
}
/* Enable chip and IRQ, disable analog sleep */
ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD,
GP2AP002_OPMOD_SSD_OPERATING |
GP2AP002_OPMOD_VCON_IRQ); if (ret) {
dev_err(gp2ap002->dev, "error setting up operation mode\n"); return ret;
}
/* Interrupt on VOUT enabled */
ret = regmap_write(gp2ap002->map, GP2AP002_CON,
GP2AP002_CON_OCON_ENABLE); if (ret)
dev_err(gp2ap002->dev, "error setting up VOUT control\n");
/* Check the device tree for the IR LED hysteresis */
ret = device_property_read_u8(dev, "sharp,proximity-far-hysteresis",
&val); if (ret) {
dev_err(dev, "failed to obtain proximity far setting\n"); return ret;
}
dev_dbg(dev, "proximity far setting %02x\n", val);
gp2ap002->hys_far = val;
ret = device_property_read_u8(dev, "sharp,proximity-close-hysteresis",
&val); if (ret) {
dev_err(dev, "failed to obtain proximity close setting\n"); return ret;
}
dev_dbg(dev, "proximity close setting %02x\n", val);
gp2ap002->hys_close = val;
/* The GP2AP002A00F has a light sensor too */ if (!gp2ap002->is_gp2ap002s00f) {
gp2ap002->alsout = devm_iio_channel_get(dev, "alsout"); if (IS_ERR(gp2ap002->alsout)) {
ret = PTR_ERR(gp2ap002->alsout);
ret = (ret == -ENODEV) ? -EPROBE_DEFER : ret; return dev_err_probe(dev, ret, "failed to get ALSOUT ADC channel\n");
}
ret = iio_get_channel_type(gp2ap002->alsout, &ch_type); if (ret < 0) return ret; if (ch_type != IIO_CURRENT) {
dev_err(dev, "wrong type of IIO channel specified for ALSOUT\n"); return -EINVAL;
}
}
gp2ap002->vdd = devm_regulator_get(dev, "vdd"); if (IS_ERR(gp2ap002->vdd)) return dev_err_probe(dev, PTR_ERR(gp2ap002->vdd), "failed to get VDD regulator\n");
gp2ap002->vio = devm_regulator_get(dev, "vio"); if (IS_ERR(gp2ap002->vio)) return dev_err_probe(dev, PTR_ERR(gp2ap002->vio), "failed to get VIO regulator\n");
/* Operating voltage 2.4V .. 3.6V according to datasheet */
ret = regulator_set_voltage(gp2ap002->vdd, 2400000, 3600000); if (ret) {
dev_err(dev, "failed to sett VDD voltage\n"); return ret;
}
/* VIO should be between 1.65V and VDD */
ret = regulator_get_voltage(gp2ap002->vdd); if (ret < 0) {
dev_err(dev, "failed to get VDD voltage\n"); return ret;
}
ret = regulator_set_voltage(gp2ap002->vio, 1650000, ret); if (ret) {
dev_err(dev, "failed to set VIO voltage\n"); return ret;
}
ret = regulator_enable(gp2ap002->vdd); if (ret) {
dev_err(dev, "failed to enable VDD regulator\n"); return ret;
}
ret = regulator_enable(gp2ap002->vio); if (ret) {
dev_err(dev, "failed to enable VIO regulator\n"); goto out_disable_vdd;
}
ret = regulator_enable(gp2ap002->vdd); if (ret) {
dev_err(dev, "failed to enable VDD regulator in resume path\n"); return ret;
}
ret = regulator_enable(gp2ap002->vio); if (ret) {
dev_err(dev, "failed to enable VIO regulator in resume path\n"); return ret;
}
msleep(20);
ret = gp2ap002_init(gp2ap002); if (ret) {
dev_err(dev, "re-initialization failed\n"); return ret;
}
/* Re-activate the IRQ */
enable_irq(gp2ap002->irq);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.