module stuff (hwmon: check hardware state, spi: try to bind spidev stuff)
This commit is contained in:
parent
46227bacb0
commit
8f1f4b1ad0
|
@ -43,6 +43,7 @@ static umode_t dmj_hwmon_is_visible(const void *data, enum hwmon_sensor_types ty
|
||||||
uint32_t attr, int ch)
|
uint32_t attr, int ch)
|
||||||
{
|
{
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
|
case hwmon_temp_type:
|
||||||
case hwmon_temp_input:
|
case hwmon_temp_input:
|
||||||
case hwmon_temp_min:
|
case hwmon_temp_min:
|
||||||
case hwmon_temp_max:
|
case hwmon_temp_max:
|
||||||
|
@ -112,19 +113,77 @@ static const struct hwmon_chip_info dmj_chip_info = {
|
||||||
.info = dmj_hwmon_info
|
.info = dmj_hwmon_info
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int dmj_hwmon_check_hw(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
uint16_t m1ver;
|
||||||
|
uint8_t curmode, m1feat;
|
||||||
|
const int ver_min = 0x0010, ver_max = 0x0010;
|
||||||
|
int ret = 0, len;
|
||||||
|
uint8_t *buf = NULL;
|
||||||
|
|
||||||
|
ret = dmj_transfer(pdev, DMJ_CMD_CFG_GET_CUR_MODE,
|
||||||
|
DMJ_XFER_FLAGS_PARSE_RESP, NULL, 0, (void**)&buf, &len);
|
||||||
|
ret = dmj_check_retval(ret, len, dev, "hwmon test 1", true, sizeof(curmode), sizeof(curmode));
|
||||||
|
if (ret < 0 || !buf) goto out;
|
||||||
|
|
||||||
|
curmode = buf[0];
|
||||||
|
kfree(buf); buf = NULL;
|
||||||
|
if (curmode != 0x1) {
|
||||||
|
dev_err(dev, "device must be in mode 1 for hwmon to work, but it is in mode %d\n", curmode);
|
||||||
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dmj_transfer(pdev, (1<<4) | DMJ_CMD_MODE_GET_VERSION,
|
||||||
|
DMJ_XFER_FLAGS_PARSE_RESP, NULL, 0, (void**)&buf, &len);
|
||||||
|
ret = dmj_check_retval(ret, len, dev, "hwmon test 2", true, sizeof(m1ver), sizeof(m1ver));
|
||||||
|
if (ret < 0 || !buf) goto out;
|
||||||
|
|
||||||
|
m1ver = (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
|
||||||
|
kfree(buf); buf = NULL;
|
||||||
|
if (m1ver > ver_max || m1ver < ver_min) {
|
||||||
|
dev_err(dev, "bad mode 1 version %04x on device, must be between %04x and %04x\n",
|
||||||
|
m1ver, ver_min, ver_max);
|
||||||
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dmj_transfer(pdev, (1<<4) | DMJ_CMD_MODE_GET_FEATURES,
|
||||||
|
DMJ_XFER_FLAGS_PARSE_RESP, NULL, 0, (void**)&buf, &len);
|
||||||
|
ret = dmj_check_retval(ret, len, dev, "hwmon test 3", true, sizeof(m1feat), sizeof(m1feat));
|
||||||
|
if (ret < 0 || !buf) goto out;
|
||||||
|
m1feat = buf[0];
|
||||||
|
kfree(buf); buf = NULL;
|
||||||
|
if (!(m1feat & DMJ_FEATURE_MODE1_I2C)) {
|
||||||
|
dev_err(dev, "device's mode 1 does not support hwmon tempsensor\n");
|
||||||
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int dmj_hwmon_probe(struct platform_device *pdev)
|
static int dmj_hwmon_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct dmj_hwmon *dmjh;
|
struct dmj_hwmon *dmjh;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = dmj_hwmon_check_hw(pdev);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "hw check failed: %d\n", ret);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
dmjh = devm_kzalloc(dev, sizeof(*dmjh), GFP_KERNEL);
|
dmjh = devm_kzalloc(dev, sizeof(*dmjh), GFP_KERNEL);
|
||||||
if (!dmjh) return -ENOMEM;
|
if (!dmjh) return -ENOMEM;
|
||||||
|
|
||||||
dmjh->pdev = pdev;
|
dmjh->pdev = pdev;
|
||||||
|
|
||||||
/* TODO: check usb stuff? (mode1, tempsensor feature) */
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, dmjh);
|
platform_set_drvdata(pdev, dmjh);
|
||||||
|
|
||||||
dmjh->hwmon_dev = hwmon_device_register_with_info(dev, HWMON_NAME, dmjh,
|
dmjh->hwmon_dev = hwmon_device_register_with_info(dev, HWMON_NAME, dmjh,
|
||||||
|
|
|
@ -224,7 +224,7 @@ static int dmj_i2c_check_hw(struct platform_device *pdev)
|
||||||
curmode = buf[0];
|
curmode = buf[0];
|
||||||
kfree(buf); buf = NULL;
|
kfree(buf); buf = NULL;
|
||||||
if (curmode != 0x1) {
|
if (curmode != 0x1) {
|
||||||
dev_err(dev, "device must be in mode 1 for ICD to work, but it is in mode %d\n", curmode);
|
dev_err(dev, "device must be in mode 1 for I2C to work, but it is in mode %d\n", curmode);
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,8 @@ struct dmj_spi {
|
||||||
uint8_t cmdmap[32];
|
uint8_t cmdmap[32];
|
||||||
|
|
||||||
spinlock_t csmap_lock;
|
spinlock_t csmap_lock;
|
||||||
|
|
||||||
|
struct spi_board_info binfo[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dmj_check_retval_sp(int ret, int len, struct device *dev,
|
static int dmj_check_retval_sp(int ret, int len, struct device *dev,
|
||||||
|
@ -169,6 +171,19 @@ static int devcaps_to_kernmode(uint16_t caps)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
static void caps_to_binfo(struct dmj_spi *dmjs, int busnum)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < dmjs->caps.num_cs; ++i) {
|
||||||
|
snprintf(dmjs->binfo[i].modalias, SPI_NAME_SIZE, "spidev");
|
||||||
|
dmjs->binfo[i].controller_data = dmjs;
|
||||||
|
dmjs->binfo[i].max_speed_hz = dmjs->caps.freq_max;
|
||||||
|
dmjs->binfo[i].bus_num = busnum;
|
||||||
|
dmjs->binfo[i].chip_select = i;
|
||||||
|
dmjs->binfo[i].mode = 0; /* shrug */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void bufconv_to_le(void *dst, const void *src, size_t len_bytes, uint8_t bpw)
|
static void bufconv_to_le(void *dst, const void *src, size_t len_bytes, uint8_t bpw)
|
||||||
{
|
{
|
||||||
|
@ -867,6 +882,15 @@ static int dmj_spi_probe(struct platform_device *pdev)
|
||||||
goto err_dereg;
|
goto err_dereg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_info(dev, "SPI bus number is %d\n", spictl->bus_num);
|
||||||
|
|
||||||
|
caps_to_binfo(dmjs, spictl->bus_num);
|
||||||
|
for (i = 0; i < dmjs->caps.num_cs; ++i) {
|
||||||
|
if (!spi_new_device(spictl, &dmjs->binfo[i])) {
|
||||||
|
dev_warn(dev, "failed to create %s device %d\n", dmjs->binfo[i].modalias, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dmj_spi_set_pinstate(dmjs, true);
|
return dmj_spi_set_pinstate(dmjs, true);
|
||||||
|
|
||||||
err_dereg:
|
err_dereg:
|
||||||
|
|
Loading…
Reference in New Issue