Commit fa33428f authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: das1800: tidy up das1800_probe()

Refactor das1800_probe() to return an errno instead of the boardinfo
pointer.

Add the board 'id' to the boardinfo to tidy up this function to clarify
the sanity check when the user provided a board name when trying to
attach to the driver.

Currently when this function probes for a boardinfo based on the board
id it returns the wrong boardinfo for the "st-da" and "hr-da" types.
This causes the analog input subdevice for those boards to not be
available. Fix the probe so that a proper boardinfo is used.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1e436ce3
......@@ -167,13 +167,6 @@ Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
#define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
enum {
das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
das1702hr_da,
das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
};
/* analog input ranges */
static const struct comedi_lrange range_ai_das1801 = {
8, {
......@@ -201,8 +194,38 @@ static const struct comedi_lrange range_ai_das1802 = {
}
};
enum das1800_boardid {
BOARD_DAS1701ST,
BOARD_DAS1701ST_DA,
BOARD_DAS1702ST,
BOARD_DAS1702ST_DA,
BOARD_DAS1702HR,
BOARD_DAS1702HR_DA,
BOARD_DAS1701AO,
BOARD_DAS1702AO,
BOARD_DAS1801ST,
BOARD_DAS1801ST_DA,
BOARD_DAS1802ST,
BOARD_DAS1802ST_DA,
BOARD_DAS1802HR,
BOARD_DAS1802HR_DA,
BOARD_DAS1801HC,
BOARD_DAS1802HC,
BOARD_DAS1801AO,
BOARD_DAS1802AO
};
/* board probe id values (hi byte of the digital input register) */
#define DAS1800_ID_ST_DA 0x3
#define DAS1800_ID_HR_DA 0x4
#define DAS1800_ID_AO 0x5
#define DAS1800_ID_HR 0x6
#define DAS1800_ID_ST 0x7
#define DAS1800_ID_HC 0x8
struct das1800_board {
const char *name;
unsigned char id;
int ai_speed; /* max conversion period in nanoseconds */
int resolution; /* bits of ai resolution */
int qram_len; /* length of card's channel / gain queue */
......@@ -218,8 +241,9 @@ struct das1800_board {
* user manual.)
*/
static const struct das1800_board das1800_boards[] = {
{
[BOARD_DAS1701ST] = {
.name = "das-1701st",
.id = DAS1800_ID_ST,
.ai_speed = 6250,
.resolution = 12,
.qram_len = 256,
......@@ -228,8 +252,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 0,
.ao_n_chan = 0,
.range_ai = &range_ai_das1801,
}, {
},
[BOARD_DAS1701ST_DA] = {
.name = "das-1701st-da",
.id = DAS1800_ID_ST_DA,
.ai_speed = 6250,
.resolution = 12,
.qram_len = 256,
......@@ -238,8 +264,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 4,
.range_ai = &range_ai_das1801,
}, {
},
[BOARD_DAS1702ST] = {
.name = "das-1702st",
.id = DAS1800_ID_ST,
.ai_speed = 6250,
.resolution = 12,
.qram_len = 256,
......@@ -248,8 +276,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 0,
.ao_n_chan = 0,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1702ST_DA] = {
.name = "das-1702st-da",
.id = DAS1800_ID_ST_DA,
.ai_speed = 6250,
.resolution = 12,
.qram_len = 256,
......@@ -258,8 +288,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 4,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1702HR] = {
.name = "das-1702hr",
.id = DAS1800_ID_HR,
.ai_speed = 20000,
.resolution = 16,
.qram_len = 256,
......@@ -268,8 +300,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 0,
.ao_n_chan = 0,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1702HR_DA] = {
.name = "das-1702hr-da",
.id = DAS1800_ID_HR_DA,
.ai_speed = 20000,
.resolution = 16,
.qram_len = 256,
......@@ -278,8 +312,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 2,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1701AO] = {
.name = "das-1701ao",
.id = DAS1800_ID_AO,
.ai_speed = 6250,
.resolution = 12,
.qram_len = 256,
......@@ -288,8 +324,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 2,
.ao_n_chan = 2,
.range_ai = &range_ai_das1801,
}, {
},
[BOARD_DAS1702AO] = {
.name = "das-1702ao",
.id = DAS1800_ID_AO,
.ai_speed = 6250,
.resolution = 12,
.qram_len = 256,
......@@ -298,8 +336,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 2,
.ao_n_chan = 2,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1801ST] = {
.name = "das-1801st",
.id = DAS1800_ID_ST,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 256,
......@@ -308,8 +348,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 0,
.ao_n_chan = 0,
.range_ai = &range_ai_das1801,
}, {
},
[BOARD_DAS1801ST_DA] = {
.name = "das-1801st-da",
.id = DAS1800_ID_ST_DA,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 256,
......@@ -318,8 +360,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 4,
.range_ai = &range_ai_das1801,
}, {
},
[BOARD_DAS1802ST] = {
.name = "das-1802st",
.id = DAS1800_ID_ST,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 256,
......@@ -328,8 +372,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 0,
.ao_n_chan = 0,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1802ST_DA] = {
.name = "das-1802st-da",
.id = DAS1800_ID_ST_DA,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 256,
......@@ -338,8 +384,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 4,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1802HR] = {
.name = "das-1802hr",
.id = DAS1800_ID_HR,
.ai_speed = 10000,
.resolution = 16,
.qram_len = 256,
......@@ -348,8 +396,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 0,
.ao_n_chan = 0,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1802HR_DA] = {
.name = "das-1802hr-da",
.id = DAS1800_ID_HR_DA,
.ai_speed = 10000,
.resolution = 16,
.qram_len = 256,
......@@ -358,8 +408,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 2,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1801HC] = {
.name = "das-1801hc",
.id = DAS1800_ID_HC,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 64,
......@@ -368,8 +420,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 2,
.range_ai = &range_ai_das1801,
}, {
},
[BOARD_DAS1802HC] = {
.name = "das-1802hc",
.id = DAS1800_ID_HC,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 64,
......@@ -378,8 +432,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 1,
.ao_n_chan = 2,
.range_ai = &range_ai_das1802,
}, {
},
[BOARD_DAS1801AO] = {
.name = "das-1801ao",
.id = DAS1800_ID_AO,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 256,
......@@ -388,8 +444,10 @@ static const struct das1800_board das1800_boards[] = {
.ao_ability = 2,
.ao_n_chan = 2,
.range_ai = &range_ai_das1801,
}, {
},
[BOARD_DAS1802AO] = {
.name = "das-1802ao",
.id = DAS1800_ID_AO,
.ai_speed = 3000,
.resolution = 12,
.qram_len = 256,
......@@ -1189,68 +1247,68 @@ static void das1800_free_dma(struct comedi_device *dev)
comedi_isadma_free(devpriv->dma);
}
static const struct das1800_board *das1800_probe(struct comedi_device *dev)
static int das1800_probe(struct comedi_device *dev)
{
const struct das1800_board *board = dev->board_ptr;
int index = board ? board - das1800_boards : -EINVAL;
int id;
unsigned char id;
id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
/*
* The dev->board_ptr will be set by comedi_device_attach() if the
* board name provided by the user matches a board->name in this
* driver. If so, this function sanity checks the id to verify that
* the board is correct.
*
*/
if (board) {
if (board->id == id)
return 0;
dev_err(dev->class_dev,
"probed id does not match board id (0x%x != 0x%x)\n",
id, board->id);
return -ENODEV;
}
/*
* If the dev->board_ptr is not set, the user is trying to attach
* an unspecified board to this driver. In this case the id is used
* to 'probe' for the correct dev->board_ptr.
* to 'probe' for the dev->board_ptr.
*/
id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
switch (id) {
case 0x3:
if (index == das1801st_da || index == das1802st_da ||
index == das1701st_da || index == das1702st_da)
return board;
index = das1801st;
case DAS1800_ID_ST_DA:
/* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */
board = &das1800_boards[BOARD_DAS1801ST_DA];
break;
case 0x4:
if (index == das1802hr_da || index == das1702hr_da)
return board;
index = das1802hr;
case DAS1800_ID_HR_DA:
/* das-1702hr-da, das-1802hr-da */
board = &das1800_boards[BOARD_DAS1802HR_DA];
break;
case 0x5:
if (index == das1801ao || index == das1802ao ||
index == das1701ao || index == das1702ao)
return board;
index = das1801ao;
case DAS1800_ID_AO:
/* das-1701ao, das-1702ao, das-1801ao, das-1802ao */
board = &das1800_boards[BOARD_DAS1801AO];
break;
case 0x6:
if (index == das1802hr || index == das1702hr)
return board;
index = das1802hr;
case DAS1800_ID_HR:
/* das-1702hr, das-1802hr */
board = &das1800_boards[BOARD_DAS1802HR];
break;
case 0x7:
if (index == das1801st || index == das1802st ||
index == das1701st || index == das1702st)
return board;
index = das1801st;
case DAS1800_ID_ST:
/* das-1701st, das-1702st, das-1801st, das-1802st */
board = &das1800_boards[BOARD_DAS1801ST];
break;
case 0x8:
if (index == das1801hc || index == das1802hc)
return board;
index = das1801hc;
case DAS1800_ID_HC:
/* das-1801hc, das-1802hc */
board = &das1800_boards[BOARD_DAS1801HC];
break;
default:
dev_err(dev->class_dev,
"Board model: probe returned 0x%x (unknown, please report)\n",
id);
return NULL;
dev_err(dev->class_dev, "invalid probe id 0x%x\n", id);
return -ENODEV;
}
dev_err(dev->class_dev,
"Board model (probed, not recommended): %s series\n",
das1800_boards[index].name);
return &das1800_boards[index];
dev->board_ptr = board;
dev->board_name = board->name;
dev_warn(dev->class_dev,
"probed id 0x%0x: %s series (not recommended)\n",
id, board->name);
return 0;
}
static int das1800_attach(struct comedi_device *dev,
......@@ -1270,13 +1328,10 @@ static int das1800_attach(struct comedi_device *dev,
if (ret)
return ret;
board = das1800_probe(dev);
if (!board) {
dev_err(dev->class_dev, "unable to determine board type\n");
return -ENODEV;
}
dev->board_ptr = board;
dev->board_name = board->name;
ret = das1800_probe(dev);
if (ret)
return ret;
board = dev->board_ptr;
/* if it is an 'ao' board with fancy analog out then we need extra io ports */
if (board->ao_ability == 2) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment