cuốn sách gpt4 ai đã làm

Làm thế nào để mã kernel biết bus spi nào đang được sử dụng?

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 04:35:18 30 4
mua khóa gpt4 Nike

Tôi đã sửa đổi tệp cây thiết bị và kích hoạt spi bằng 4 chân GPIO hỗ trợ pinmux và chuyển từ chức năng gpio sang spi. Nhưng trong mã nhân Linux, làm sao mã này biết được bus/pin spi nào được sử dụng? Ví dụ: tôi đã tìm thấy trình điều khiển nhân Linux: max1111.c, điều khiển chip ADC spi. Nhưng tôi đã kiểm tra mã của nó và không tìm thấy bus/pin spi được chỉ định ở đâu.

Tôi đã dán max1111.c bên dưới.

/*
* max1111.c - +2.7V, ADC 8 bit nối tiếp, công suất thấp, đa kênh
*
* Dựa trên Arch/arm/mach-pxa/corgi_ssp.c
*
* Bản quyền (C) 2004-2005 Richard Purdie
*
* Bản quyền (C) 2008 Marvell International Ltd.
* Eric Miao
*
* Chương trình này là phần mềm miễn phí; bạn có thể phân phối lại và/hoặc sửa đổi nó
* nó theo các điều khoản của Giấy phép Công cộng GNU phiên bản 2 như
* được xuất bản bởi Tổ chức Phần mềm Tự do.
*/

#include
#include
#include
#include
#include
#include
#include
#include

chip enum {max1110, max1111, max1112, max1113 };

#define MAX1111_TX_BUF_SIZE 1
#define MAX1111_RX_BUF_SIZE 2

/* Lệnh MAX1111 */
#define MAX1111_CTRL_PD0 (1u << 0)
#define MAX1111_CTRL_PD1 (1u << 1)
#define MAX1111_CTRL_SGL (1u << 2)
#define MAX1111_CTRL_UNI (1u << 3)
#define MAX1110_CTRL_SEL_SH (4)
#define MAX1111_CTRL_SEL_SH (5) /* LƯU Ý: bit 4 bị bỏ qua */
#define MAX1111_CTRL_STR (1u << 7)

cấu trúc max1111_data {
struct spi_device *spi;
thiết bị cấu trúc *hwmon_dev;
struct tin nhắn spi_message;
struct spi_transfer xfer[2];
uint8_t tx_buf[MAX1111_TX_BUF_SIZE];
uint8_t rx_buf[MAX1111_RX_BUF_SIZE];
cấu trúc mutex drvdata_lock;
/* bảo vệ tin nhắn, xfer và bộ đệm khỏi nhiều truy cập */
int sel_sh;
int lsb;
};

int tĩnh max1111_read(thiết bị cấu trúc *dev, kênh int)
{
cấu trúc max1111_data *data = dev_get_drvdata(dev);
uint8_t v1, v2;
int lỗi;

/* ghi vào cấu trúc drvdata không an toàn cho luồng, đợi trên mutex */
mutex_lock(&data->drvdata_lock);

data->tx_buf[0] = (kênh << data->sel_sh) |
MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 |
MAX1111_CTRL_SGL | MAX1111_CTRL_UNI MAX1111_CTRL_STR;

err = spi_sync(data->spi, &data->msg);
nếu (lỗi < 0) {
dev_err(dev, "spi_sync không thành công với %d\n", err);
mutex_unlock(&data->drvdata_lock);
trả lại lỗi;
}

v1 = dữ liệu->rx_buf[0];
v2 = dữ liệu->rx_buf[1];

mutex_unlock(&data->drvdata_lock);

nếu ((v1 & 0xc0) || (v2 & 0x3f))
trả về -EINVAL;

trở về (v1 << 2) | (v2 >> 6);
}

#ifdef CONFIG_SHARPSL_PM
cấu trúc tĩnh max1111_data *the_max1111;

int max1111_read_channel(kênh int)
{
return max1111_read(&the_max1111->spi->dev, kênh);
}
EXPORT_SYMBOL(max1111_read_channel);
#endif

/*
* LƯU Ý: Các thiết bị SPI không có thuộc tính 'tên' mặc định, đó là
* có thể được các ứng dụng hwmon sử dụng để phân biệt giữa
* các thiết bị khác nhau, hãy thêm thuộc tính tên một cách rõ ràng tại đây.
*/
ssize_t tĩnh show_name(thiết bị cấu trúc *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
}

ssize_t tĩnh show_adc(thiết bị cấu trúc *dev,
struct device_attribute *attr, char *buf)
{
cấu trúc max1111_data *data = dev_get_drvdata(dev);
kênh int = to_sensor_dev_attr(attr)->index;
int ret;

ret = max1111_read(dev, kênh);
if (ret < 0)
return ret;

/*
* Giả sử điện áp tham chiếu là 2.048V hoặc 4.096V, với 8 bit
* mẫu. Trọng lượng LSB là 8mV hoặc 16mV tùy thuộc vào loại chip.
*/
return sprintf(buf, "%d\n", ret * data->lsb);
}

#define MAX1111_ADC_ATTR(_id) \
SENSOR_DEVICE_ATTR(trong##_id##_input, S_IRUGO, show_adc, NULL, _id)

DEVICE_ATTR tĩnh (tên, S_IRUGO, show_name, NULL);
tĩnh MAX1111_ADC_ATTR(0);
tĩnh MAX1111_ADC_ATTR(1);
tĩnh MAX1111_ADC_ATTR(2);
tĩnh MAX1111_ADC_ATTR(3);
tĩnh MAX1111_ADC_ATTR(4);
tĩnh MAX1111_ADC_ATTR(5);
tĩnh MAX1111_ADC_ATTR(6);
tĩnh MAX1111_ADC_ATTR(7);

thuộc tính cấu trúc tĩnh *max1111_attributes[] = {
&dev_attr_name.attr,
&cảm biến_dev_attr_in0_input.dev_attr.attr,
&cảm biến_dev_attr_in1_input.dev_attr.attr,
&cảm biến_dev_attr_in2_input.dev_attr.attr,
&cảm biến_dev_attr_in3_input.dev_attr.attr,
NULL,
};

const tĩnh struct attribute_group max1111_attr_group = {
.attrs = max1111_attributes,
};

thuộc tính cấu trúc tĩnh *max1110_attributes[] = {
&cảm biến_dev_attr_in4_input.dev_attr.attr,
&cảm biến_dev_attr_in5_input.dev_attr.attr,
&cảm biến_dev_attr_in6_input.dev_attr.attr,
&cảm biến_dev_attr_in7_input.dev_attr.attr,
NULL,
};

const tĩnh struct attribute_group max1110_attr_group = {
.attrs = max1110_attributes,
};

int tĩnh setup_transfer(struct max1111_data *data)
{
cấu trúc spi_message *m;
cấu trúc spi_transfer *x;

m = &data->msg;
x = &data->xfer[0];

spi_message_init(m);

x->tx_buf = &data->tx_buf[0];
x->len = MAX1111_TX_BUF_SIZE;
spi_message_add_tail(x, m);

x++;
x->rx_buf = &data->rx_buf[0];
x->len = MAX1111_RX_BUF_SIZE;
spi_message_add_tail(x, m);

return 0;
}

int tĩnh max1111_probe(struct spi_device *spi)
{
chip chip enum = spi_get_device_id(spi)->driver_data;
cấu trúc max1111_data *data;
int lỗi;

spi->bits_per_word = 8;
spi->chế độ = SPI_MODE_0;
err = spi_setup(spi);
nếu (lỗi < 0)
trả lại lỗi;

data = devm_kzalloc(&spi->dev, sizeof(struct max1111_data), GFP_KERNEL);
nếu (dữ liệu == NULL) {
dev_err(&spi->dev, "không phân bổ được bộ nhớ\n");
trả về -ENOMEM;
}

công tắc (chip) {
trường hợp max1110:
dữ liệu->lsb = 8;
dữ liệu->sel_sh = MAX1110_CTRL_SEL_SH;
phá vỡ;
trường hợp max1111:
dữ liệu->lsb = 8;
dữ liệu->sel_sh = MAX1111_CTRL_SEL_SH;
phá vỡ;
trường hợp max1112:
dữ liệu->lsb = 16;
dữ liệu->sel_sh = MAX1110_CTRL_SEL_SH;
phá vỡ;
trường hợp max1113:
dữ liệu->lsb = 16;
dữ liệu->sel_sh = MAX1111_CTRL_SEL_SH;
phá vỡ;
}
err = setup_transfer(dữ liệu);
if (err)
trả lại lỗi;

mutex_init(&data->drvdata_lock);

dữ liệu->spi = spi;
spi_set_drvdata(spi, dữ liệu);

err = sysfs_create_group(&spi->dev.kobj, &max1111_attr_group);
if (err) {
dev_err(&spi->dev, "không tạo được nhóm thuộc tính\n");
trả lại lỗi;
}
if (chip == max1110 || chip == max1112) {
err = sysfs_create_group(&spi->dev.kobj, &max1110_attr_group);
if (err) {
dev_err(&spi->dev,
"không tạo được nhóm thuộc tính mở rộng\n");
đi tới err_remove;
}
}

dữ liệu->hwmon_dev = hwmon_device_register(&spi->dev);
if (IS_ERR(data->hwmon_dev)) {
dev_err(&spi->dev, "không tạo được thiết bị hwmon\n");
lỗi = PTR_ERR(dữ liệu->hwmon_dev);
đi tới err_remove;
}

#ifdef CONFIG_SHARPSL_PM
the_max1111 = dữ liệu;
#endif
return 0;

err_remove:
sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group);
sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
trả lại lỗi;
}

int tĩnh max1111_remove(struct spi_device *spi)
{
struct max1111_data *data = spi_get_drvdata(spi);

hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group);
sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
mutex_destroy(&data->drvdata_lock);
return 0;
}

cấu trúc const tĩnh spi_device_id max1111_ids[] = {
{"max1110", max1110 },
{"max1111", max1111 },
{"max1112", max1112 },
{"max1113", max1113 },
{ },
};
MODULE_DEVICE_TABLE(spi, max1111_ids);

cấu trúc tĩnh spi_driver max1111_driver = {
.driver = {
.name = "max1111",
.chủ sở hữu = THIS_MODULE,
},
.id_table = max1111_ids,
.probe = max1111_probe,
.remove = max1111_remove,
};

module_spi_driver(max1111_driver);

MODULE_AUTHOR("Eric Miao ");
MODULE_DESCRIPTION("Trình điều khiển ADC MAX1110/MAX1111/MAX1112/MAX1113");
MODULE_LICENSE("GPL");

câu trả lời hay nhất

Trình điều khiển thiết bị SPI (trong trường hợp của bạn tối đa1111) trong giai đoạn phát hiện (max1111_probe) lấy một con trỏ tới Bộ điều khiển SPI bên dưới (cấu trúc spi_device *spi) con trỏ>). Trình điều khiển nên sử dụng nó để gửi yêu cầu đến Bộ điều khiển (ví dụ: sử dụng spi_sync ). Trình điều khiển không biết mã PIN mà Bộ điều khiển SPI sử dụng.

Bộ điều khiển SPI chuyển tới trình điều khiển thiết bị SPI những gì? Thiết bị SPI phải được khai báo trong tệp DTS trong nút Bộ điều khiển SPI. Bộ điều khiển được khởi tạo từ nút Bộ điều khiển SPI được chuyển đến thiết bị thăm dò.

Bộ điều khiển SPI có thể là phần cứng (SoC cụ thể) hoặc SPI-GPIO .Trong trường hợp SPI phần cứng, các chân thường được dành riêng và chỉ định trong SoC TRM. Trong trường hợp SPI-GPIO, tên GPIO được chỉ định trong thuộc tính DTS của SPI-GPIO. Tên thuộc tính là: gpio-sck, gpio-miso, gpio-mosi, num-chipselects và cs-gpios (list).

Về c - làm thế nào mã hạt nhân biết bus spi nào đang được sử dụng? , chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/31070439/

30 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress