I'm trying to use a UBlox NEO-7M GPS receiver on an Odroid-C1 board.
By default the GPS module works in the SPI's first mode. That's why I use this userspace code snippet to select the proper SPI mode.
int mode = SPI_MODE_0;
ret = ioctl(spi_fd, SPI_IOC_WR_MODE, &mode);
if (ret < 0) {
perror("can't set spi mode");
exit(1);
}
After that I'm trying to read a byte at a time and send it to stdout. It doesn't work out, though.
After some thought I plugged my Salaea's logic analyzer and got this picture
This doesn't seem right at all. If I'm not mistaken SCL should be driven low between transactions.
I tried to fix this issue by pulling SCL line down in spicc.ko kernel module (I use this kernel with a RT-patch to compile the module. RT-patch doesn't really make any difference. The issue is experienced on a vanilla kernel as well).
Thus, the main question is: is pulling this pin down the right thing to do?
As I further looked into the code I noticed that spicc_set_mode() does set mode as described in Amlogic S805 datasheet (section 15.5.3 describes CONREG register layout). Maybe that's not enough?
Either way, what is the intended way to pull down a pin using Linux' pinctrl interface?
I'm also trying to understand spicc's code. It uses
ret = of_property_read_string(pdev->dev.of_node, "pinctrl-names", &prop_name);
if(ret || IS_ERR(prop_name)) {
dev_err(&pdev->dev, "match pinctrl-names failed!\n");
return -ENODEV;
}
pdata->pinctrl = devm_pinctrl_get_select(&pdev->dev, prop_name);
if(IS_ERR(pdata->pinctrl)) {
dev_err(&pdev->dev, "pinmux error\n");
return -ENODEV;
}
dev_info(&pdev->dev, "pinctrl_name = %s\n", prop_name);
to get pinctrl handle from Device Tree Blob, doesn't it? Am I supposed to edit .dts file to pull down the pin or it can be done in runtime?
At first I tried to use it by dumb brutal force code but it didn't work (pinctrl is already using this pin as declared in .dts file in spicc section).
static void spicc_sclk_init(void)
{
int ret;
int gpio;
char *owner = "spicc_sclk";
char *pin_name = "GPIOX_8";
gpio = amlogic_gpio_name_map_num(pin_name);
if (gpio < 0) {
printk(KERN_ERR "amlogic_gpio_name_map_num() failed. gpio: %d\n", gpio);
goto out_map;
}
ret = amlogic_gpio_request(gpio, owner);
if (ret < 0) {
printk(KERN_ERR "amlogic_gpio_request_one() failed. ret: %d\n", ret);
goto out_request;
}
ret = amlogic_set_pull_up_down(gpio, 0, owner);
if (ret < 0) {
printk(KERN_ERR "amlogic_set_pull_up_down() failed. ret: %d\n", ret);
goto out_pull_up_down;
}
out_pull_up_down:
out_request:
out_map:
;
}
Does anyone have any suggestions how this issue can be fixed?
PS: I use the same userspace code on a RPi with a same UBlox and the code does work and modes are switched as expected.
I tried to hook up another SPI-driven device to Odroid-C1 (it was Invensense's MPU9260, if that matters.) and did it work. My guess that it's just more SPI mode tolerant.