Char/Misc patches for 3.5-rc1
Here are a few various char/misc tree patches for the 3.5-rc1 merge window. Nothing major here at all, just different driver updates and some parport dead code removal. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) iEYEABECAAYFAk+7qxoACgkQMUfUDdst+ynz0gCggUMf6y60T1rPVT7h2Ab3iy5k 9d0An0U607GRDK1e5lwbZdGuuRkfBwRi =NpES -----END PGP SIGNATURE----- Merge tag 'char-misc-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull Char/Misc patches from Greg Kroah-Hartman: "Here are a few various char/misc tree patches for the 3.5-rc1 merge window. Nothing major here at all, just different driver updates and some parport dead code removal. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'char-misc-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: parport: remove unused dead code from lowlevel drivers xilinx_hwicap: reset XHI_MAX_RETRIES xilinx_hwicap: add support for virtex6 FPGAs Support M95040 SPI EEPROM misc: add support for bmp18x chips to the bmp085 driver misc: bmp085: add device tree properties misc: clean up bmp085 driver misc: do not mark exported functions __devexit misc: add missing __devexit_p() annotations pch_phub: delete duplicate definitions misc: Fix irq leak in max8997_muic_probe error path
This commit is contained in:
Коммит
fb2123fad3
|
@ -0,0 +1,20 @@
|
|||
BMP085/BMP18x digital pressure sensors
|
||||
|
||||
Required properties:
|
||||
- compatible: bosch,bmp085
|
||||
|
||||
Optional properties:
|
||||
- chip-id: configurable chip id for non-default chip revisions
|
||||
- temp-measurement-period: temperature measurement period (milliseconds)
|
||||
- default-oversampling: default oversampling value to be used at startup,
|
||||
value range is 0-3 with rising sensitivity.
|
||||
|
||||
Example:
|
||||
|
||||
pressure@77 {
|
||||
compatible = "bosch,bmp085";
|
||||
reg = <0x77>;
|
||||
chip-id = <10>;
|
||||
temp-measurement-period = <100>;
|
||||
default-oversampling = <2>;
|
||||
};
|
После Ширина: | Высота: | Размер: 519 B |
|
@ -8,6 +8,7 @@ amcc Applied Micro Circuits Corporation (APM, formally AMCC)
|
|||
apm Applied Micro Circuits Corporation (APM)
|
||||
arm ARM Ltd.
|
||||
atmel Atmel Corporation
|
||||
bosch Bosch Sensortec GmbH
|
||||
cavium Cavium, Inc.
|
||||
chrp Common Hardware Reference Platform
|
||||
cortina Cortina Systems, Inc.
|
||||
|
|
|
@ -167,6 +167,7 @@ static const struct config_registers v4_config_registers = {
|
|||
.BOOTSTS = UNIMPLEMENTED,
|
||||
.CTL_1 = UNIMPLEMENTED,
|
||||
};
|
||||
|
||||
static const struct config_registers v5_config_registers = {
|
||||
.CRC = 0,
|
||||
.FAR = 1,
|
||||
|
@ -192,6 +193,31 @@ static const struct config_registers v5_config_registers = {
|
|||
.CTL_1 = 19,
|
||||
};
|
||||
|
||||
static const struct config_registers v6_config_registers = {
|
||||
.CRC = 0,
|
||||
.FAR = 1,
|
||||
.FDRI = 2,
|
||||
.FDRO = 3,
|
||||
.CMD = 4,
|
||||
.CTL = 5,
|
||||
.MASK = 6,
|
||||
.STAT = 7,
|
||||
.LOUT = 8,
|
||||
.COR = 9,
|
||||
.MFWR = 10,
|
||||
.FLR = UNIMPLEMENTED,
|
||||
.KEY = UNIMPLEMENTED,
|
||||
.CBC = 11,
|
||||
.IDCODE = 12,
|
||||
.AXSS = 13,
|
||||
.C0R_1 = 14,
|
||||
.CSOB = 15,
|
||||
.WBSTAR = 16,
|
||||
.TIMER = 17,
|
||||
.BOOTSTS = 22,
|
||||
.CTL_1 = 24,
|
||||
};
|
||||
|
||||
/**
|
||||
* hwicap_command_desync - Send a DESYNC command to the ICAP port.
|
||||
* @drvdata: a pointer to the drvdata.
|
||||
|
@ -744,6 +770,8 @@ static int __devinit hwicap_of_probe(struct platform_device *op,
|
|||
regs = &v4_config_registers;
|
||||
} else if (!strcmp(family, "virtex5")) {
|
||||
regs = &v5_config_registers;
|
||||
} else if (!strcmp(family, "virtex6")) {
|
||||
regs = &v6_config_registers;
|
||||
}
|
||||
}
|
||||
return hwicap_setup(&op->dev, id ? *id : -1, &res, config,
|
||||
|
@ -785,6 +813,8 @@ static int __devinit hwicap_drv_probe(struct platform_device *pdev)
|
|||
regs = &v4_config_registers;
|
||||
} else if (!strcmp(family, "virtex5")) {
|
||||
regs = &v5_config_registers;
|
||||
} else if (!strcmp(family, "virtex6")) {
|
||||
regs = &v6_config_registers;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ struct hwicap_driver_config {
|
|||
};
|
||||
|
||||
/* Number of times to poll the done regsiter */
|
||||
#define XHI_MAX_RETRIES 10
|
||||
#define XHI_MAX_RETRIES 5000
|
||||
|
||||
/************ Constant Definitions *************/
|
||||
|
||||
|
|
|
@ -452,14 +452,32 @@ config ARM_CHARLCD
|
|||
still useful.
|
||||
|
||||
config BMP085
|
||||
tristate "BMP085 digital pressure sensor"
|
||||
bool
|
||||
depends on SYSFS
|
||||
|
||||
config BMP085_I2C
|
||||
tristate "BMP085 digital pressure sensor on I2C"
|
||||
select BMP085
|
||||
select REGMAP_I2C
|
||||
depends on I2C && SYSFS
|
||||
help
|
||||
If you say yes here you get support for the Bosch Sensortec
|
||||
BMP085 digital pressure sensor.
|
||||
Say Y here if you want to support Bosch Sensortec's digital pressure
|
||||
sensor hooked to an I2C bus.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called bmp085.
|
||||
module will be called bmp085-i2c.
|
||||
|
||||
config BMP085_SPI
|
||||
tristate "BMP085 digital pressure sensor on SPI"
|
||||
select BMP085
|
||||
select REGMAP_SPI
|
||||
depends on SPI_MASTER && SYSFS
|
||||
help
|
||||
Say Y here if you want to support Bosch Sensortec's digital pressure
|
||||
sensor hooked to an SPI bus.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called bmp085-spi.
|
||||
|
||||
config PCH_PHUB
|
||||
tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
|
||||
|
|
|
@ -11,6 +11,8 @@ obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
|
|||
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
|
||||
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
|
||||
obj-$(CONFIG_BMP085) += bmp085.o
|
||||
obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o
|
||||
obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o
|
||||
obj-$(CONFIG_ICS932S401) += ics932s401.o
|
||||
obj-$(CONFIG_LKDTM) += lkdtm.o
|
||||
obj-$(CONFIG_TIFM_CORE) += tifm_core.o
|
||||
|
|
|
@ -749,7 +749,7 @@ exit:
|
|||
}
|
||||
EXPORT_SYMBOL(ad_dpot_probe);
|
||||
|
||||
__devexit int ad_dpot_remove(struct device *dev)
|
||||
int ad_dpot_remove(struct device *dev)
|
||||
{
|
||||
struct dpot_data *data = dev_get_drvdata(dev);
|
||||
int i;
|
||||
|
|
|
@ -248,7 +248,7 @@ static const struct i2c_device_id bh1780_id[] = {
|
|||
|
||||
static struct i2c_driver bh1780_driver = {
|
||||
.probe = bh1780_probe,
|
||||
.remove = bh1780_remove,
|
||||
.remove = __devexit_p(bh1780_remove),
|
||||
.id_table = bh1780_id,
|
||||
.driver = {
|
||||
.name = "bh1780",
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Bosch Sensortec GmbH
|
||||
* Copyright (c) 2012 Unixphere AB
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/err.h>
|
||||
#include "bmp085.h"
|
||||
|
||||
#define BMP085_I2C_ADDRESS 0x77
|
||||
|
||||
static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
|
||||
I2C_CLIENT_END };
|
||||
|
||||
static int bmp085_i2c_detect(struct i2c_client *client,
|
||||
struct i2c_board_info *info)
|
||||
{
|
||||
if (client->addr != BMP085_I2C_ADDRESS)
|
||||
return -ENODEV;
|
||||
|
||||
return bmp085_detect(&client->dev);
|
||||
}
|
||||
|
||||
static int __devinit bmp085_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int err;
|
||||
struct regmap *regmap = devm_regmap_init_i2c(client,
|
||||
&bmp085_regmap_config);
|
||||
|
||||
if (IS_ERR(regmap)) {
|
||||
err = PTR_ERR(regmap);
|
||||
dev_err(&client->dev, "Failed to init regmap: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return bmp085_probe(&client->dev, regmap);
|
||||
}
|
||||
|
||||
static int bmp085_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return bmp085_remove(&client->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id bmp085_of_match[] = {
|
||||
{ .compatible = "bosch,bmp085", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bmp085_of_match);
|
||||
|
||||
static const struct i2c_device_id bmp085_id[] = {
|
||||
{ BMP085_NAME, 0 },
|
||||
{ "bmp180", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, bmp085_id);
|
||||
|
||||
static struct i2c_driver bmp085_i2c_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = BMP085_NAME,
|
||||
.of_match_table = bmp085_of_match
|
||||
},
|
||||
.id_table = bmp085_id,
|
||||
.probe = bmp085_i2c_probe,
|
||||
.remove = __devexit_p(bmp085_i2c_remove),
|
||||
|
||||
.detect = bmp085_i2c_detect,
|
||||
.address_list = normal_i2c
|
||||
};
|
||||
|
||||
module_i2c_driver(bmp085_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
|
||||
MODULE_DESCRIPTION("BMP085 I2C bus driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Bosch Sensortec GmbH
|
||||
* Copyright (c) 2012 Unixphere AB
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/err.h>
|
||||
#include "bmp085.h"
|
||||
|
||||
static int __devinit bmp085_spi_probe(struct spi_device *client)
|
||||
{
|
||||
int err;
|
||||
struct regmap *regmap;
|
||||
|
||||
client->bits_per_word = 8;
|
||||
err = spi_setup(client);
|
||||
if (err < 0) {
|
||||
dev_err(&client->dev, "spi_setup failed!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
regmap = devm_regmap_init_spi(client, &bmp085_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
err = PTR_ERR(regmap);
|
||||
dev_err(&client->dev, "Failed to init regmap: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return bmp085_probe(&client->dev, regmap);
|
||||
}
|
||||
|
||||
static int bmp085_spi_remove(struct spi_device *client)
|
||||
{
|
||||
return bmp085_remove(&client->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id bmp085_of_match[] = {
|
||||
{ .compatible = "bosch,bmp085", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bmp085_of_match);
|
||||
|
||||
static const struct spi_device_id bmp085_id[] = {
|
||||
{ "bmp180", 0 },
|
||||
{ "bmp181", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, bmp085_id);
|
||||
|
||||
static struct spi_driver bmp085_spi_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = BMP085_NAME,
|
||||
.of_match_table = bmp085_of_match
|
||||
},
|
||||
.id_table = bmp085_id,
|
||||
.probe = bmp085_spi_probe,
|
||||
.remove = __devexit_p(bmp085_spi_remove)
|
||||
};
|
||||
|
||||
static int __init bmp085_spi_init(void)
|
||||
{
|
||||
return spi_register_driver(&bmp085_spi_driver);
|
||||
}
|
||||
|
||||
static void __exit bmp085_spi_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&bmp085_spi_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
|
||||
MODULE_DESCRIPTION("BMP085 SPI bus driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(bmp085_spi_init);
|
||||
module_exit(bmp085_spi_exit);
|
|
@ -1,62 +1,62 @@
|
|||
/* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
|
||||
|
||||
This driver supports the bmp085 digital barometric pressure
|
||||
and temperature sensor from Bosch Sensortec. The datasheet
|
||||
is available from their website:
|
||||
http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
|
||||
|
||||
A pressure measurement is issued by reading from pressure0_input.
|
||||
The return value ranges from 30000 to 110000 pascal with a resulution
|
||||
of 1 pascal (0.01 millibar) which enables measurements from 9000m above
|
||||
to 500m below sea level.
|
||||
|
||||
The temperature can be read from temp0_input. Values range from
|
||||
-400 to 850 representing the ambient temperature in degree celsius
|
||||
multiplied by 10.The resolution is 0.1 celsius.
|
||||
|
||||
Because ambient pressure is temperature dependent, a temperature
|
||||
measurement will be executed automatically even if the user is reading
|
||||
from pressure0_input. This happens if the last temperature measurement
|
||||
has been executed more then one second ago.
|
||||
|
||||
To decrease RMS noise from pressure measurements, the bmp085 can
|
||||
autonomously calculate the average of up to eight samples. This is
|
||||
set up by writing to the oversampling sysfs file. Accepted values
|
||||
are 0, 1, 2 and 3. 2^x when x is the value written to this file
|
||||
specifies the number of samples used to calculate the ambient pressure.
|
||||
RMS noise is specified with six pascal (without averaging) and decreases
|
||||
down to 3 pascal when using an oversampling setting of 3.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
* Copyright (c) 2012 Bosch Sensortec GmbH
|
||||
* Copyright (c) 2012 Unixphere AB
|
||||
*
|
||||
* This driver supports the bmp085 and bmp18x digital barometric pressure
|
||||
* and temperature sensors from Bosch Sensortec. The datasheets
|
||||
* are available from their website:
|
||||
* http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
|
||||
* http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP180-DS000-07.pdf
|
||||
*
|
||||
* A pressure measurement is issued by reading from pressure0_input.
|
||||
* The return value ranges from 30000 to 110000 pascal with a resulution
|
||||
* of 1 pascal (0.01 millibar) which enables measurements from 9000m above
|
||||
* to 500m below sea level.
|
||||
*
|
||||
* The temperature can be read from temp0_input. Values range from
|
||||
* -400 to 850 representing the ambient temperature in degree celsius
|
||||
* multiplied by 10.The resolution is 0.1 celsius.
|
||||
*
|
||||
* Because ambient pressure is temperature dependent, a temperature
|
||||
* measurement will be executed automatically even if the user is reading
|
||||
* from pressure0_input. This happens if the last temperature measurement
|
||||
* has been executed more then one second ago.
|
||||
*
|
||||
* To decrease RMS noise from pressure measurements, the bmp085 can
|
||||
* autonomously calculate the average of up to eight samples. This is
|
||||
* set up by writing to the oversampling sysfs file. Accepted values
|
||||
* are 0, 1, 2 and 3. 2^x when x is the value written to this file
|
||||
* specifies the number of samples used to calculate the ambient pressure.
|
||||
* RMS noise is specified with six pascal (without averaging) and decreases
|
||||
* down to 3 pascal when using an oversampling setting of 3.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include "bmp085.h"
|
||||
|
||||
|
||||
#define BMP085_I2C_ADDRESS 0x77
|
||||
#define BMP085_CHIP_ID 0x55
|
||||
|
||||
#define BMP085_CALIBRATION_DATA_START 0xAA
|
||||
#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
|
||||
#define BMP085_CHIP_ID_REG 0xD0
|
||||
#define BMP085_VERSION_REG 0xD1
|
||||
#define BMP085_CTRL_REG 0xF4
|
||||
#define BMP085_TEMP_MEASUREMENT 0x2E
|
||||
#define BMP085_PRESSURE_MEASUREMENT 0x34
|
||||
|
@ -65,12 +65,6 @@
|
|||
#define BMP085_CONVERSION_REGISTER_XLSB 0xF8
|
||||
#define BMP085_TEMP_CONVERSION_TIME 5
|
||||
|
||||
#define BMP085_CLIENT_NAME "bmp085"
|
||||
|
||||
|
||||
static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
|
||||
I2C_CLIENT_END };
|
||||
|
||||
struct bmp085_calibration_data {
|
||||
s16 AC1, AC2, AC3;
|
||||
u16 AC4, AC5, AC6;
|
||||
|
@ -78,35 +72,30 @@ struct bmp085_calibration_data {
|
|||
s16 MB, MC, MD;
|
||||
};
|
||||
|
||||
|
||||
/* Each client has this additional data */
|
||||
struct bmp085_data {
|
||||
struct i2c_client *client;
|
||||
struct mutex lock;
|
||||
struct bmp085_calibration_data calibration;
|
||||
u32 raw_temperature;
|
||||
u32 raw_pressure;
|
||||
unsigned char oversampling_setting;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct mutex lock;
|
||||
struct bmp085_calibration_data calibration;
|
||||
u8 oversampling_setting;
|
||||
u32 raw_temperature;
|
||||
u32 raw_pressure;
|
||||
u32 temp_measurement_period;
|
||||
unsigned long last_temp_measurement;
|
||||
s32 b6; /* calculated temperature correction coefficient */
|
||||
u8 chip_id;
|
||||
s32 b6; /* calculated temperature correction coefficient */
|
||||
};
|
||||
|
||||
|
||||
static s32 bmp085_read_calibration_data(struct i2c_client *client)
|
||||
static s32 bmp085_read_calibration_data(struct bmp085_data *data)
|
||||
{
|
||||
u16 tmp[BMP085_CALIBRATION_DATA_LENGTH];
|
||||
struct bmp085_data *data = i2c_get_clientdata(client);
|
||||
struct bmp085_calibration_data *cali = &(data->calibration);
|
||||
s32 status = i2c_smbus_read_i2c_block_data(client,
|
||||
BMP085_CALIBRATION_DATA_START,
|
||||
BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16),
|
||||
(u8 *)tmp);
|
||||
s32 status = regmap_bulk_read(data->regmap,
|
||||
BMP085_CALIBRATION_DATA_START, (u8 *)tmp,
|
||||
(BMP085_CALIBRATION_DATA_LENGTH << 1));
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
if (status != BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16))
|
||||
return -EIO;
|
||||
|
||||
cali->AC1 = be16_to_cpu(tmp[0]);
|
||||
cali->AC2 = be16_to_cpu(tmp[1]);
|
||||
cali->AC3 = be16_to_cpu(tmp[2]);
|
||||
|
@ -121,30 +110,26 @@ static s32 bmp085_read_calibration_data(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static s32 bmp085_update_raw_temperature(struct bmp085_data *data)
|
||||
{
|
||||
u16 tmp;
|
||||
s32 status;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
|
||||
BMP085_TEMP_MEASUREMENT);
|
||||
if (status != 0) {
|
||||
dev_err(&data->client->dev,
|
||||
status = regmap_write(data->regmap, BMP085_CTRL_REG,
|
||||
BMP085_TEMP_MEASUREMENT);
|
||||
if (status < 0) {
|
||||
dev_err(data->dev,
|
||||
"Error while requesting temperature measurement.\n");
|
||||
goto exit;
|
||||
}
|
||||
msleep(BMP085_TEMP_CONVERSION_TIME);
|
||||
|
||||
status = i2c_smbus_read_i2c_block_data(data->client,
|
||||
BMP085_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
|
||||
if (status < 0)
|
||||
goto exit;
|
||||
if (status != sizeof(tmp)) {
|
||||
dev_err(&data->client->dev,
|
||||
status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB,
|
||||
&tmp, sizeof(tmp));
|
||||
if (status < 0) {
|
||||
dev_err(data->dev,
|
||||
"Error while reading temperature measurement result\n");
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
data->raw_temperature = be16_to_cpu(tmp);
|
||||
|
@ -162,10 +147,11 @@ static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
|
|||
s32 status;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
|
||||
BMP085_PRESSURE_MEASUREMENT + (data->oversampling_setting<<6));
|
||||
if (status != 0) {
|
||||
dev_err(&data->client->dev,
|
||||
status = regmap_write(data->regmap, BMP085_CTRL_REG,
|
||||
BMP085_PRESSURE_MEASUREMENT +
|
||||
(data->oversampling_setting << 6));
|
||||
if (status < 0) {
|
||||
dev_err(data->dev,
|
||||
"Error while requesting pressure measurement.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
@ -174,14 +160,11 @@ static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
|
|||
msleep(2+(3 << data->oversampling_setting));
|
||||
|
||||
/* copy data into a u32 (4 bytes), but skip the first byte. */
|
||||
status = i2c_smbus_read_i2c_block_data(data->client,
|
||||
BMP085_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
|
||||
if (status < 0)
|
||||
goto exit;
|
||||
if (status != 3) {
|
||||
dev_err(&data->client->dev,
|
||||
status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB,
|
||||
((u8 *)&tmp)+1, 3);
|
||||
if (status < 0) {
|
||||
dev_err(data->dev,
|
||||
"Error while reading pressure measurement results\n");
|
||||
status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
data->raw_pressure = be32_to_cpu((tmp));
|
||||
|
@ -193,7 +176,6 @@ exit:
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function starts the temperature measurement and returns the value
|
||||
* in tenth of a degree celsius.
|
||||
|
@ -205,7 +187,7 @@ static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature)
|
|||
int status;
|
||||
|
||||
status = bmp085_update_raw_temperature(data);
|
||||
if (status != 0)
|
||||
if (status < 0)
|
||||
goto exit;
|
||||
|
||||
x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
|
||||
|
@ -222,8 +204,10 @@ exit:
|
|||
/*
|
||||
* This function starts the pressure measurement and returns the value
|
||||
* in millibar. Since the pressure depends on the ambient temperature,
|
||||
* a temperature measurement is executed if the last known value is older
|
||||
* than one second.
|
||||
* a temperature measurement is executed according to the given temperature
|
||||
* measurement period (default is 1 sec boundary). This period could vary
|
||||
* and needs to be adjusted according to the sensor environment, i.e. if big
|
||||
* temperature variations then the temperature needs to be read out often.
|
||||
*/
|
||||
static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
|
||||
{
|
||||
|
@ -234,16 +218,16 @@ static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
|
|||
int status;
|
||||
|
||||
/* alt least every second force an update of the ambient temperature */
|
||||
if (data->last_temp_measurement == 0 ||
|
||||
time_is_before_jiffies(data->last_temp_measurement + 1*HZ)) {
|
||||
if ((data->last_temp_measurement == 0) ||
|
||||
time_is_before_jiffies(data->last_temp_measurement + 1*HZ)) {
|
||||
status = bmp085_get_temperature(data, NULL);
|
||||
if (status != 0)
|
||||
goto exit;
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = bmp085_update_raw_pressure(data);
|
||||
if (status != 0)
|
||||
goto exit;
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
x1 = (data->b6 * data->b6) >> 12;
|
||||
x1 *= cali->B2;
|
||||
|
@ -274,15 +258,14 @@ static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
|
|||
|
||||
*pressure = p;
|
||||
|
||||
exit:
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the chip-internal oversampling. Valid values are 0..3.
|
||||
* The chip will use 2^oversampling samples for internal averaging.
|
||||
* This influences the measurement time and the accuracy; larger values
|
||||
* increase both. The datasheet gives on overview on how measurement time,
|
||||
* increase both. The datasheet gives an overview on how measurement time,
|
||||
* accuracy and noise correlate.
|
||||
*/
|
||||
static void bmp085_set_oversampling(struct bmp085_data *data,
|
||||
|
@ -306,22 +289,25 @@ static ssize_t set_oversampling(struct device *dev,
|
|||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct bmp085_data *data = i2c_get_clientdata(client);
|
||||
struct bmp085_data *data = dev_get_drvdata(dev);
|
||||
unsigned long oversampling;
|
||||
int success = strict_strtoul(buf, 10, &oversampling);
|
||||
if (success == 0) {
|
||||
int err = kstrtoul(buf, 10, &oversampling);
|
||||
|
||||
if (err == 0) {
|
||||
mutex_lock(&data->lock);
|
||||
bmp085_set_oversampling(data, oversampling);
|
||||
mutex_unlock(&data->lock);
|
||||
return count;
|
||||
}
|
||||
return success;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t show_oversampling(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct bmp085_data *data = i2c_get_clientdata(client);
|
||||
struct bmp085_data *data = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
|
||||
}
|
||||
static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
|
||||
|
@ -333,11 +319,10 @@ static ssize_t show_temperature(struct device *dev,
|
|||
{
|
||||
int temperature;
|
||||
int status;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct bmp085_data *data = i2c_get_clientdata(client);
|
||||
struct bmp085_data *data = dev_get_drvdata(dev);
|
||||
|
||||
status = bmp085_get_temperature(data, &temperature);
|
||||
if (status != 0)
|
||||
if (status < 0)
|
||||
return status;
|
||||
else
|
||||
return sprintf(buf, "%d\n", temperature);
|
||||
|
@ -350,11 +335,10 @@ static ssize_t show_pressure(struct device *dev,
|
|||
{
|
||||
int pressure;
|
||||
int status;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct bmp085_data *data = i2c_get_clientdata(client);
|
||||
struct bmp085_data *data = dev_get_drvdata(dev);
|
||||
|
||||
status = bmp085_get_pressure(data, &pressure);
|
||||
if (status != 0)
|
||||
if (status < 0)
|
||||
return status;
|
||||
else
|
||||
return sprintf(buf, "%d\n", pressure);
|
||||
|
@ -373,38 +357,70 @@ static const struct attribute_group bmp085_attr_group = {
|
|||
.attrs = bmp085_attributes,
|
||||
};
|
||||
|
||||
static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info)
|
||||
int bmp085_detect(struct device *dev)
|
||||
{
|
||||
if (client->addr != BMP085_I2C_ADDRESS)
|
||||
return -ENODEV;
|
||||
struct bmp085_data *data = dev_get_drvdata(dev);
|
||||
unsigned int id;
|
||||
int ret;
|
||||
|
||||
if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID)
|
||||
ret = regmap_read(data->regmap, BMP085_CHIP_ID_REG, &id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (id != data->chip_id)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bmp085_detect);
|
||||
|
||||
static int bmp085_init_client(struct i2c_client *client)
|
||||
static void __init bmp085_get_of_properties(struct bmp085_data *data)
|
||||
{
|
||||
unsigned char version;
|
||||
int status;
|
||||
struct bmp085_data *data = i2c_get_clientdata(client);
|
||||
data->client = client;
|
||||
status = bmp085_read_calibration_data(client);
|
||||
if (status != 0)
|
||||
goto exit;
|
||||
version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG);
|
||||
data->last_temp_measurement = 0;
|
||||
data->oversampling_setting = 3;
|
||||
mutex_init(&data->lock);
|
||||
dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n",
|
||||
(version & 0x0F), (version & 0xF0) >> 4);
|
||||
exit:
|
||||
return status;
|
||||
#ifdef CONFIG_OF
|
||||
struct device_node *np = data->dev->of_node;
|
||||
u32 prop;
|
||||
|
||||
if (!np)
|
||||
return;
|
||||
|
||||
if (!of_property_read_u32(np, "chip-id", &prop))
|
||||
data->chip_id = prop & 0xff;
|
||||
|
||||
if (!of_property_read_u32(np, "temp-measurement-period", &prop))
|
||||
data->temp_measurement_period = (prop/100)*HZ;
|
||||
|
||||
if (!of_property_read_u32(np, "default-oversampling", &prop))
|
||||
data->oversampling_setting = prop & 0xff;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __devinit bmp085_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int bmp085_init_client(struct bmp085_data *data)
|
||||
{
|
||||
int status = bmp085_read_calibration_data(data);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* default settings */
|
||||
data->chip_id = BMP085_CHIP_ID;
|
||||
data->last_temp_measurement = 0;
|
||||
data->temp_measurement_period = 1*HZ;
|
||||
data->oversampling_setting = 3;
|
||||
|
||||
bmp085_get_of_properties(data);
|
||||
|
||||
mutex_init(&data->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct regmap_config bmp085_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(bmp085_regmap_config);
|
||||
|
||||
__devinit int bmp085_probe(struct device *dev, struct regmap *regmap)
|
||||
{
|
||||
struct bmp085_data *data;
|
||||
int err = 0;
|
||||
|
@ -415,58 +431,48 @@ static int __devinit bmp085_probe(struct i2c_client *client,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* default settings after POR */
|
||||
data->oversampling_setting = 0x00;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
dev_set_drvdata(dev, data);
|
||||
data->dev = dev;
|
||||
data->regmap = regmap;
|
||||
|
||||
/* Initialize the BMP085 chip */
|
||||
err = bmp085_init_client(client);
|
||||
if (err != 0)
|
||||
err = bmp085_init_client(data);
|
||||
if (err < 0)
|
||||
goto exit_free;
|
||||
|
||||
err = bmp085_detect(dev);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "%s: chip_id failed!\n", BMP085_NAME);
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
/* Register sysfs hooks */
|
||||
err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group);
|
||||
err = sysfs_create_group(&dev->kobj, &bmp085_attr_group);
|
||||
if (err)
|
||||
goto exit_free;
|
||||
|
||||
dev_info(&data->client->dev, "Successfully initialized bmp085!\n");
|
||||
goto exit;
|
||||
dev_info(dev, "Successfully initialized %s!\n", BMP085_NAME);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free:
|
||||
kfree(data);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bmp085_probe);
|
||||
|
||||
static int __devexit bmp085_remove(struct i2c_client *client)
|
||||
int bmp085_remove(struct device *dev)
|
||||
{
|
||||
sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
struct bmp085_data *data = dev_get_drvdata(dev);
|
||||
|
||||
sysfs_remove_group(&data->dev->kobj, &bmp085_attr_group);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bmp085_remove);
|
||||
|
||||
static const struct i2c_device_id bmp085_id[] = {
|
||||
{ "bmp085", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, bmp085_id);
|
||||
|
||||
static struct i2c_driver bmp085_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bmp085"
|
||||
},
|
||||
.id_table = bmp085_id,
|
||||
.probe = bmp085_probe,
|
||||
.remove = __devexit_p(bmp085_remove),
|
||||
|
||||
.detect = bmp085_detect,
|
||||
.address_list = normal_i2c
|
||||
};
|
||||
|
||||
module_i2c_driver(bmp085_driver);
|
||||
|
||||
MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
|
||||
MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com>");
|
||||
MODULE_DESCRIPTION("BMP085 driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Bosch Sensortec GmbH
|
||||
* Copyright (c) 2012 Unixphere AB
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _BMP085_H
|
||||
#define _BMP085_H
|
||||
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define BMP085_NAME "bmp085"
|
||||
|
||||
extern struct regmap_config bmp085_regmap_config;
|
||||
|
||||
int bmp085_probe(struct device *dev, struct regmap *regmap);
|
||||
int bmp085_remove(struct device *dev);
|
||||
int bmp085_detect(struct device *dev);
|
||||
|
||||
#endif
|
|
@ -50,6 +50,7 @@ struct at25_data {
|
|||
#define AT25_SR_BP1 0x08
|
||||
#define AT25_SR_WPEN 0x80 /* writeprotect enable */
|
||||
|
||||
#define AT25_INSTR_BIT3 0x08 /* Additional address bit in instr */
|
||||
|
||||
#define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */
|
||||
|
||||
|
@ -75,6 +76,7 @@ at25_ee_read(
|
|||
ssize_t status;
|
||||
struct spi_transfer t[2];
|
||||
struct spi_message m;
|
||||
u8 instr;
|
||||
|
||||
if (unlikely(offset >= at25->bin.size))
|
||||
return 0;
|
||||
|
@ -84,7 +86,12 @@ at25_ee_read(
|
|||
return count;
|
||||
|
||||
cp = command;
|
||||
*cp++ = AT25_READ;
|
||||
|
||||
instr = AT25_READ;
|
||||
if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
|
||||
if (offset >= (1U << (at25->addrlen * 8)))
|
||||
instr |= AT25_INSTR_BIT3;
|
||||
*cp++ = instr;
|
||||
|
||||
/* 8/16/24-bit address is written MSB first */
|
||||
switch (at25->addrlen) {
|
||||
|
@ -167,14 +174,14 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
|
|||
/* For write, rollover is within the page ... so we write at
|
||||
* most one page, then manually roll over to the next page.
|
||||
*/
|
||||
bounce[0] = AT25_WRITE;
|
||||
mutex_lock(&at25->lock);
|
||||
do {
|
||||
unsigned long timeout, retries;
|
||||
unsigned segment;
|
||||
unsigned offset = (unsigned) off;
|
||||
u8 *cp = bounce + 1;
|
||||
u8 *cp = bounce;
|
||||
int sr;
|
||||
u8 instr;
|
||||
|
||||
*cp = AT25_WREN;
|
||||
status = spi_write(at25->spi, cp, 1);
|
||||
|
@ -184,6 +191,12 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
|
|||
break;
|
||||
}
|
||||
|
||||
instr = AT25_WRITE;
|
||||
if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
|
||||
if (offset >= (1U << (at25->addrlen * 8)))
|
||||
instr |= AT25_INSTR_BIT3;
|
||||
*cp++ = instr;
|
||||
|
||||
/* 8/16/24-bit address is written MSB first */
|
||||
switch (at25->addrlen) {
|
||||
default: /* case 3 */
|
||||
|
|
|
@ -440,10 +440,6 @@ static int __devinit max8997_muic_probe(struct platform_device *pdev)
|
|||
"failed: irq request (IRQ: %d,"
|
||||
" error :%d)\n",
|
||||
muic_irq->irq, ret);
|
||||
|
||||
for (i = i - 1; i >= 0; i--)
|
||||
free_irq(muic_irq->irq, info);
|
||||
|
||||
goto err_irq;
|
||||
}
|
||||
}
|
||||
|
@ -457,6 +453,8 @@ static int __devinit max8997_muic_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
|
||||
err_irq:
|
||||
while (--i >= 0)
|
||||
free_irq(pdata->irq_base + muic_irqs[i].irq, info);
|
||||
err_pdata:
|
||||
kfree(info);
|
||||
err_kfree:
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
#define PCI_VENDOR_ID_ROHM 0x10db
|
||||
#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
|
||||
|
||||
/* Macros for ML7213 */
|
||||
#define PCI_VENDOR_ID_ROHM 0x10db
|
||||
#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
|
||||
|
||||
/* Macros for ML7223 */
|
||||
#define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */
|
||||
#define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */
|
||||
|
|
|
@ -888,7 +888,7 @@ static struct pci_driver pti_pci_driver = {
|
|||
.name = PCINAME,
|
||||
.id_table = pci_ids,
|
||||
.probe = pti_pci_probe,
|
||||
.remove = pti_pci_remove,
|
||||
.remove = __devexit_p(pti_pci_remove),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,23 +48,6 @@ static unsigned char amiga_read_data(struct parport *p)
|
|||
return ciaa.prb;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static unsigned char control_pc_to_amiga(unsigned char control)
|
||||
{
|
||||
unsigned char ret = 0;
|
||||
|
||||
if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
|
||||
;
|
||||
if (control & PARPORT_CONTROL_INIT) /* INITP */
|
||||
/* reset connected to cpu reset pin */;
|
||||
if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */
|
||||
/* Not connected */;
|
||||
if (control & PARPORT_CONTROL_STROBE) /* Strobe */
|
||||
/* Handled only directly by hardware */;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char control_amiga_to_pc(unsigned char control)
|
||||
{
|
||||
return PARPORT_CONTROL_SELECT |
|
||||
|
@ -95,25 +78,6 @@ static unsigned char amiga_frob_control( struct parport *p, unsigned char mask,
|
|||
return old;
|
||||
}
|
||||
|
||||
#if 0 /* currently unused */
|
||||
static unsigned char status_pc_to_amiga(unsigned char status)
|
||||
{
|
||||
unsigned char ret = 1;
|
||||
|
||||
if (status & PARPORT_STATUS_BUSY) /* Busy */
|
||||
ret &= ~1;
|
||||
if (status & PARPORT_STATUS_ACK) /* Ack */
|
||||
/* handled in hardware */;
|
||||
if (status & PARPORT_STATUS_PAPEROUT) /* PaperOut */
|
||||
ret |= 2;
|
||||
if (status & PARPORT_STATUS_SELECT) /* select */
|
||||
ret |= 4;
|
||||
if (status & PARPORT_STATUS_ERROR) /* error */
|
||||
/* not connected */;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char status_amiga_to_pc(unsigned char status)
|
||||
{
|
||||
unsigned char ret = PARPORT_STATUS_BUSY | PARPORT_STATUS_ACK | PARPORT_STATUS_ERROR;
|
||||
|
|
|
@ -130,15 +130,6 @@ parport_atari_data_forward(struct parport *p)
|
|||
static void
|
||||
parport_atari_data_reverse(struct parport *p)
|
||||
{
|
||||
#if 0 /* too dangerous, can kill sound chip */
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
/* Soundchip port B as input. */
|
||||
sound_ym.rd_data_reg_sel = 7;
|
||||
sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~0x40;
|
||||
local_irq_restore(flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct parport_operations parport_atari_ops = {
|
||||
|
|
|
@ -147,25 +147,6 @@ DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val);
|
|||
return old;
|
||||
}
|
||||
|
||||
#if 0 /* currently unused */
|
||||
static unsigned char status_pc_to_mfc3(unsigned char status)
|
||||
{
|
||||
unsigned char ret = 1;
|
||||
|
||||
if (status & PARPORT_STATUS_BUSY) /* Busy */
|
||||
ret &= ~1;
|
||||
if (status & PARPORT_STATUS_ACK) /* Ack */
|
||||
ret |= 8;
|
||||
if (status & PARPORT_STATUS_PAPEROUT) /* PaperOut */
|
||||
ret |= 2;
|
||||
if (status & PARPORT_STATUS_SELECT) /* select */
|
||||
ret |= 4;
|
||||
if (status & PARPORT_STATUS_ERROR) /* error */
|
||||
ret |= 16;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char status_mfc3_to_pc(unsigned char status)
|
||||
{
|
||||
unsigned char ret = PARPORT_STATUS_BUSY;
|
||||
|
@ -184,14 +165,6 @@ static unsigned char status_mfc3_to_pc(unsigned char status)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if 0 /* currently unused */
|
||||
static void mfc3_write_status( struct parport *p, unsigned char status)
|
||||
{
|
||||
DPRINTK(KERN_DEBUG "write_status %02x\n",status);
|
||||
pia(p)->ppra = (pia(p)->ppra & 0xe0) | status_pc_to_mfc3(status);
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char mfc3_read_status(struct parport *p)
|
||||
{
|
||||
unsigned char status;
|
||||
|
@ -201,14 +174,6 @@ DPRINTK(KERN_DEBUG "read_status %02x\n", status);
|
|||
return status;
|
||||
}
|
||||
|
||||
#if 0 /* currently unused */
|
||||
static void mfc3_change_mode( struct parport *p, int m)
|
||||
{
|
||||
/* XXX: This port only has one mode, and I am
|
||||
not sure about the corresponding PC-style mode*/
|
||||
}
|
||||
#endif
|
||||
|
||||
static int use_cnt = 0;
|
||||
|
||||
static irqreturn_t mfc3_interrupt(int irq, void *dev_id)
|
||||
|
|
|
@ -197,54 +197,6 @@ static int change_mode(struct parport *p, int m)
|
|||
ECR_WRITE(p, oecr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PARPORT_1284
|
||||
/* Find FIFO lossage; FIFO is reset */
|
||||
#if 0
|
||||
static int get_fifo_residue(struct parport *p)
|
||||
{
|
||||
int residue;
|
||||
int cnfga;
|
||||
const struct parport_pc_private *priv = p->physport->private_data;
|
||||
|
||||
/* Adjust for the contents of the FIFO. */
|
||||
for (residue = priv->fifo_depth; ; residue--) {
|
||||
if (inb(ECONTROL(p)) & 0x2)
|
||||
/* Full up. */
|
||||
break;
|
||||
|
||||
outb(0, FIFO(p));
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG "%s: %d PWords were left in FIFO\n", p->name,
|
||||
residue);
|
||||
|
||||
/* Reset the FIFO. */
|
||||
frob_set_mode(p, ECR_PS2);
|
||||
|
||||
/* Now change to config mode and clean up. FIXME */
|
||||
frob_set_mode(p, ECR_CNF);
|
||||
cnfga = inb(CONFIGA(p));
|
||||
printk(KERN_DEBUG "%s: cnfgA contains 0x%02x\n", p->name, cnfga);
|
||||
|
||||
if (!(cnfga & (1<<2))) {
|
||||
printk(KERN_DEBUG "%s: Accounting for extra byte\n", p->name);
|
||||
residue++;
|
||||
}
|
||||
|
||||
/* Don't care about partial PWords until support is added for
|
||||
* PWord != 1 byte. */
|
||||
|
||||
/* Back to PS2 mode. */
|
||||
frob_set_mode(p, ECR_PS2);
|
||||
|
||||
DPRINTK(KERN_DEBUG
|
||||
"*** get_fifo_residue: done residue collecting (ecr = 0x%2.2x)\n",
|
||||
inb(ECONTROL(p)));
|
||||
return residue;
|
||||
}
|
||||
#endif /* 0 */
|
||||
#endif /* IEEE 1284 support */
|
||||
#endif /* FIFO support */
|
||||
|
||||
/*
|
||||
|
@ -940,234 +892,6 @@ static size_t parport_pc_ecp_write_block_pio(struct parport *port,
|
|||
|
||||
return written;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static size_t parport_pc_ecp_read_block_pio(struct parport *port,
|
||||
void *buf, size_t length,
|
||||
int flags)
|
||||
{
|
||||
size_t left = length;
|
||||
size_t fifofull;
|
||||
int r;
|
||||
const int fifo = FIFO(port);
|
||||
const struct parport_pc_private *priv = port->physport->private_data;
|
||||
const int fifo_depth = priv->fifo_depth;
|
||||
char *bufp = buf;
|
||||
|
||||
port = port->physport;
|
||||
DPRINTK(KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n");
|
||||
dump_parport_state("enter fcn", port);
|
||||
|
||||
/* Special case: a timeout of zero means we cannot call schedule().
|
||||
* Also if O_NONBLOCK is set then use the default implementation. */
|
||||
if (port->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
|
||||
return parport_ieee1284_ecp_read_data(port, buf,
|
||||
length, flags);
|
||||
|
||||
if (port->ieee1284.mode == IEEE1284_MODE_ECPRLE) {
|
||||
/* If the peripheral is allowed to send RLE compressed
|
||||
* data, it is possible for a byte to expand to 128
|
||||
* bytes in the FIFO. */
|
||||
fifofull = 128;
|
||||
} else {
|
||||
fifofull = fifo_depth;
|
||||
}
|
||||
|
||||
/* If the caller wants less than a full FIFO's worth of data,
|
||||
* go through software emulation. Otherwise we may have to throw
|
||||
* away data. */
|
||||
if (length < fifofull)
|
||||
return parport_ieee1284_ecp_read_data(port, buf,
|
||||
length, flags);
|
||||
|
||||
if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE) {
|
||||
/* change to reverse-idle phase (must be in forward-idle) */
|
||||
|
||||
/* Event 38: Set nAutoFd low (also make sure nStrobe is high) */
|
||||
parport_frob_control(port,
|
||||
PARPORT_CONTROL_AUTOFD
|
||||
| PARPORT_CONTROL_STROBE,
|
||||
PARPORT_CONTROL_AUTOFD);
|
||||
parport_pc_data_reverse(port); /* Must be in PS2 mode */
|
||||
udelay(5);
|
||||
/* Event 39: Set nInit low to initiate bus reversal */
|
||||
parport_frob_control(port,
|
||||
PARPORT_CONTROL_INIT,
|
||||
0);
|
||||
/* Event 40: Wait for nAckReverse (PError) to go low */
|
||||
r = parport_wait_peripheral(port, PARPORT_STATUS_PAPEROUT, 0);
|
||||
if (r) {
|
||||
printk(KERN_DEBUG "%s: PE timeout Event 40 (%d) "
|
||||
"in ecp_read_block_pio\n", port->name, r);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up ECP FIFO mode.*/
|
||||
/* parport_pc_frob_control(port,
|
||||
PARPORT_CONTROL_STROBE |
|
||||
PARPORT_CONTROL_AUTOFD,
|
||||
PARPORT_CONTROL_AUTOFD); */
|
||||
r = change_mode(port, ECR_ECP); /* ECP FIFO */
|
||||
if (r)
|
||||
printk(KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n",
|
||||
port->name);
|
||||
|
||||
port->ieee1284.phase = IEEE1284_PH_REV_DATA;
|
||||
|
||||
/* the first byte must be collected manually */
|
||||
dump_parport_state("pre 43", port);
|
||||
/* Event 43: Wait for nAck to go low */
|
||||
r = parport_wait_peripheral(port, PARPORT_STATUS_ACK, 0);
|
||||
if (r) {
|
||||
/* timed out while reading -- no data */
|
||||
printk(KERN_DEBUG "PIO read timed out (initial byte)\n");
|
||||
goto out_no_data;
|
||||
}
|
||||
/* read byte */
|
||||
*bufp++ = inb(DATA(port));
|
||||
left--;
|
||||
dump_parport_state("43-44", port);
|
||||
/* Event 44: nAutoFd (HostAck) goes high to acknowledge */
|
||||
parport_pc_frob_control(port,
|
||||
PARPORT_CONTROL_AUTOFD,
|
||||
0);
|
||||
dump_parport_state("pre 45", port);
|
||||
/* Event 45: Wait for nAck to go high */
|
||||
/* r = parport_wait_peripheral(port, PARPORT_STATUS_ACK,
|
||||
PARPORT_STATUS_ACK); */
|
||||
dump_parport_state("post 45", port);
|
||||
r = 0;
|
||||
if (r) {
|
||||
/* timed out while waiting for peripheral to respond to ack */
|
||||
printk(KERN_DEBUG "ECP PIO read timed out (waiting for nAck)\n");
|
||||
|
||||
/* keep hold of the byte we've got already */
|
||||
goto out_no_data;
|
||||
}
|
||||
/* Event 46: nAutoFd (HostAck) goes low to accept more data */
|
||||
parport_pc_frob_control(port,
|
||||
PARPORT_CONTROL_AUTOFD,
|
||||
PARPORT_CONTROL_AUTOFD);
|
||||
|
||||
|
||||
dump_parport_state("rev idle", port);
|
||||
/* Do the transfer. */
|
||||
while (left > fifofull) {
|
||||
int ret;
|
||||
unsigned long expire = jiffies + port->cad->timeout;
|
||||
unsigned char ecrval = inb(ECONTROL(port));
|
||||
|
||||
if (need_resched() && time_before(jiffies, expire))
|
||||
/* Can't yield the port. */
|
||||
schedule();
|
||||
|
||||
/* At this point, the FIFO may already be full. In
|
||||
* that case ECP is already holding back the
|
||||
* peripheral (assuming proper design) with a delayed
|
||||
* handshake. Work fast to avoid a peripheral
|
||||
* timeout. */
|
||||
|
||||
if (ecrval & 0x01) {
|
||||
/* FIFO is empty. Wait for interrupt. */
|
||||
dump_parport_state("FIFO empty", port);
|
||||
|
||||
/* Anyone else waiting for the port? */
|
||||
if (port->waithead) {
|
||||
printk(KERN_DEBUG "Somebody wants the port\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear serviceIntr */
|
||||
ECR_WRITE(port, ecrval & ~(1<<2));
|
||||
false_alarm:
|
||||
dump_parport_state("waiting", port);
|
||||
ret = parport_wait_event(port, HZ);
|
||||
DPRINTK(KERN_DEBUG "parport_wait_event returned %d\n",
|
||||
ret);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = 0;
|
||||
if (!time_before(jiffies, expire)) {
|
||||
/* Timed out. */
|
||||
dump_parport_state("timeout", port);
|
||||
printk(KERN_DEBUG "PIO read timed out\n");
|
||||
break;
|
||||
}
|
||||
ecrval = inb(ECONTROL(port));
|
||||
if (!(ecrval & (1<<2))) {
|
||||
if (need_resched() &&
|
||||
time_before(jiffies, expire)) {
|
||||
schedule();
|
||||
}
|
||||
goto false_alarm;
|
||||
}
|
||||
|
||||
/* Depending on how the FIFO threshold was
|
||||
* set, how long interrupt service took, and
|
||||
* how fast the peripheral is, we might be
|
||||
* lucky and have a just filled FIFO. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ecrval & 0x02) {
|
||||
/* FIFO is full. */
|
||||
dump_parport_state("FIFO full", port);
|
||||
insb(fifo, bufp, fifo_depth);
|
||||
bufp += fifo_depth;
|
||||
left -= fifo_depth;
|
||||
continue;
|
||||
}
|
||||
|
||||
DPRINTK(KERN_DEBUG
|
||||
"*** ecp_read_block_pio: reading one byte from the FIFO\n");
|
||||
|
||||
/* FIFO not filled. We will cycle this loop for a while
|
||||
* and either the peripheral will fill it faster,
|
||||
* tripping a fast empty with insb, or we empty it. */
|
||||
*bufp++ = inb(fifo);
|
||||
left--;
|
||||
}
|
||||
|
||||
/* scoop up anything left in the FIFO */
|
||||
while (left && !(inb(ECONTROL(port) & 0x01))) {
|
||||
*bufp++ = inb(fifo);
|
||||
left--;
|
||||
}
|
||||
|
||||
port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
|
||||
dump_parport_state("rev idle2", port);
|
||||
|
||||
out_no_data:
|
||||
|
||||
/* Go to forward idle mode to shut the peripheral up (event 47). */
|
||||
parport_frob_control(port, PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT);
|
||||
|
||||
/* event 49: PError goes high */
|
||||
r = parport_wait_peripheral(port,
|
||||
PARPORT_STATUS_PAPEROUT,
|
||||
PARPORT_STATUS_PAPEROUT);
|
||||
if (r) {
|
||||
printk(KERN_DEBUG
|
||||
"%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n",
|
||||
port->name, r);
|
||||
}
|
||||
|
||||
port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
|
||||
|
||||
/* Finish up. */
|
||||
{
|
||||
int lost = get_fifo_residue(port);
|
||||
if (lost)
|
||||
/* Shouldn't happen with compliant peripherals. */
|
||||
printk(KERN_DEBUG "%s: DATA LOSS (%d bytes)!\n",
|
||||
port->name, lost);
|
||||
}
|
||||
|
||||
dump_parport_state("fwd idle", port);
|
||||
return length - left;
|
||||
}
|
||||
#endif /* 0 */
|
||||
#endif /* IEEE 1284 support */
|
||||
#endif /* Allowed to use FIFO/DMA */
|
||||
|
||||
|
|
|
@ -82,27 +82,6 @@ static unsigned char parport_sunbpp_read_data(struct parport *p)
|
|||
return sbus_readb(®s->p_dr);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void control_pc_to_sunbpp(struct parport *p, unsigned char status)
|
||||
{
|
||||
struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
|
||||
unsigned char value_tcr = sbus_readb(®s->p_tcr);
|
||||
unsigned char value_or = sbus_readb(®s->p_or);
|
||||
|
||||
if (status & PARPORT_CONTROL_STROBE)
|
||||
value_tcr |= P_TCR_DS;
|
||||
if (status & PARPORT_CONTROL_AUTOFD)
|
||||
value_or |= P_OR_AFXN;
|
||||
if (status & PARPORT_CONTROL_INIT)
|
||||
value_or |= P_OR_INIT;
|
||||
if (status & PARPORT_CONTROL_SELECT)
|
||||
value_or |= P_OR_SLCT_IN;
|
||||
|
||||
sbus_writeb(value_or, ®s->p_or);
|
||||
sbus_writeb(value_tcr, ®s->p_tcr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char status_sunbpp_to_pc(struct parport *p)
|
||||
{
|
||||
struct bpp_regs __iomem *regs = (struct bpp_regs __iomem *)p->base;
|
||||
|
|
|
@ -20,6 +20,16 @@ struct spi_eeprom {
|
|||
#define EE_ADDR3 0x0004 /* 24 bit addrs */
|
||||
#define EE_READONLY 0x0008 /* disallow writes */
|
||||
|
||||
/*
|
||||
* Certain EEPROMS have a size that is larger than the number of address
|
||||
* bytes would allow (e.g. like M95040 from ST that has 512 Byte size
|
||||
* but uses only one address byte (A0 to A7) for addressing.) For
|
||||
* the extra address bit (A8, A16 or A24) bit 3 of the instruction byte
|
||||
* is used. This instruction bit is normally defined as don't care for
|
||||
* other AT25 like chips.
|
||||
*/
|
||||
#define EE_INSTR_BIT3_IS_ADDR 0x0010
|
||||
|
||||
/* for exporting this chip's data to other kernel code */
|
||||
void (*setup)(struct memory_accessor *mem, void *context);
|
||||
void *context;
|
||||
|
|
Загрузка…
Ссылка в новой задаче