Lines Matching +full:page +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0+
10 #include <linux/mfd/rave-sp.h>
12 #include <linux/nvmem-provider.h>
18 * enum rave_sp_eeprom_access_type - Supported types of EEPROM access
29 * enum rave_sp_eeprom_header_size - EEPROM command header sizes
43 * struct rave_sp_eeprom_page - RAVE SP EEPROM page
59 * struct rave_sp_eeprom - RAVE SP EEPROM device
76 * rave_sp_eeprom_io - Low-level part of EEPROM page access
80 * @idx: number of the EEPROM page
81 * @page: Data to write or buffer to store result (via page->data)
83 * This function does all of the low-level work required to perform a
93 struct rave_sp_eeprom_page *page) in rave_sp_eeprom_io() argument
96 const unsigned int data_size = is_write ? sizeof(page->data) : 0; in rave_sp_eeprom_io()
97 const unsigned int cmd_size = eeprom->header_size + data_size; in rave_sp_eeprom_io()
99 is_write ? sizeof(*page) - sizeof(page->data) : sizeof(*page); in rave_sp_eeprom_io()
100 unsigned int offset = 0; in rave_sp_eeprom_io() local
101 u8 cmd[RAVE_SP_EEPROM_HEADER_MAX + sizeof(page->data)]; in rave_sp_eeprom_io()
105 return -EINVAL; in rave_sp_eeprom_io()
107 cmd[offset++] = eeprom->address; in rave_sp_eeprom_io()
108 cmd[offset++] = 0; in rave_sp_eeprom_io()
109 cmd[offset++] = type; in rave_sp_eeprom_io()
110 cmd[offset++] = idx; in rave_sp_eeprom_io()
114 * are talkin to EEPROM that uses 16-bit page numbers and we in rave_sp_eeprom_io()
117 if (offset < eeprom->header_size) in rave_sp_eeprom_io()
118 cmd[offset++] = idx >> 8; in rave_sp_eeprom_io()
122 * no-op in rave_sp_eeprom_io()
124 memcpy(&cmd[offset], page->data, data_size); in rave_sp_eeprom_io()
126 ret = rave_sp_exec(eeprom->sp, cmd, cmd_size, page, rsp_size); in rave_sp_eeprom_io()
130 if (page->type != type) in rave_sp_eeprom_io()
131 return -EPROTO; in rave_sp_eeprom_io()
133 if (!page->success) in rave_sp_eeprom_io()
134 return -EIO; in rave_sp_eeprom_io()
140 * rave_sp_eeprom_page_access - Access single EEPROM page
144 * @offset: Offset within EEPROM to access
148 * This function performs a generic access to a single page or a
149 * portion thereof. Requested access MUST NOT cross the EEPROM page
158 unsigned int offset, u8 *data, in rave_sp_eeprom_page_access() argument
161 const unsigned int page_offset = offset % RAVE_SP_EEPROM_PAGE_SIZE; in rave_sp_eeprom_page_access()
162 const unsigned int page_nr = offset / RAVE_SP_EEPROM_PAGE_SIZE; in rave_sp_eeprom_page_access()
163 struct rave_sp_eeprom_page page; in rave_sp_eeprom_page_access() local
168 * to do is crossing EEPROM page boundary. Normally this in rave_sp_eeprom_page_access()
172 if (WARN_ON(data_len > sizeof(page.data) - page_offset)) in rave_sp_eeprom_page_access()
173 return -EINVAL; in rave_sp_eeprom_page_access()
178 * to fill the rest of the page with correct data. in rave_sp_eeprom_page_access()
182 page_nr, &page); in rave_sp_eeprom_page_access()
187 memcpy(&page.data[page_offset], data, data_len); in rave_sp_eeprom_page_access()
190 ret = rave_sp_eeprom_io(eeprom, type, page_nr, &page); in rave_sp_eeprom_page_access()
195 * Since we receive the result of the read via 'page.data' in rave_sp_eeprom_page_access()
199 memcpy(data, &page.data[page_offset], data_len); in rave_sp_eeprom_page_access()
205 * rave_sp_eeprom_access - Access EEPROM data
209 * @offset: Offset within EEPROM to access
214 * arbitrary offset (not necessary page aligned) of arbitrary length
215 * (is not constrained by EEPROM page size).
222 unsigned int offset, u8 *data, in rave_sp_eeprom_access() argument
230 mutex_lock(&eeprom->mutex); in rave_sp_eeprom_access()
232 head = offset % RAVE_SP_EEPROM_PAGE_SIZE; in rave_sp_eeprom_access()
238 * not 32-byte aligned, we need to access only data up in rave_sp_eeprom_access()
239 * to a page boundary to avoid corssing it in in rave_sp_eeprom_access()
243 chunk = RAVE_SP_EEPROM_PAGE_SIZE - head; in rave_sp_eeprom_access()
259 ret = rave_sp_eeprom_page_access(eeprom, type, offset, in rave_sp_eeprom_access()
264 residue -= chunk; in rave_sp_eeprom_access()
265 offset += chunk; in rave_sp_eeprom_access()
269 mutex_unlock(&eeprom->mutex); in rave_sp_eeprom_access()
273 static int rave_sp_eeprom_reg_read(void *eeprom, unsigned int offset, in rave_sp_eeprom_reg_read() argument
277 offset, val, bytes); in rave_sp_eeprom_reg_read()
280 static int rave_sp_eeprom_reg_write(void *eeprom, unsigned int offset, in rave_sp_eeprom_reg_write() argument
284 offset, val, bytes); in rave_sp_eeprom_reg_write()
289 struct device *dev = &pdev->dev; in rave_sp_eeprom_probe()
290 struct rave_sp *sp = dev_get_drvdata(dev->parent); in rave_sp_eeprom_probe()
291 struct device_node *np = dev->of_node; in rave_sp_eeprom_probe()
299 return -EINVAL; in rave_sp_eeprom_probe()
305 * page. in rave_sp_eeprom_probe()
309 return -EINVAL; in rave_sp_eeprom_probe()
314 return -ENOMEM; in rave_sp_eeprom_probe()
316 eeprom->address = reg[0]; in rave_sp_eeprom_probe()
317 eeprom->sp = sp; in rave_sp_eeprom_probe()
318 eeprom->dev = dev; in rave_sp_eeprom_probe()
321 eeprom->header_size = RAVE_SP_EEPROM_HEADER_BIG; in rave_sp_eeprom_probe()
323 eeprom->header_size = RAVE_SP_EEPROM_HEADER_SMALL; in rave_sp_eeprom_probe()
325 mutex_init(&eeprom->mutex); in rave_sp_eeprom_probe()
327 config.id = -1; in rave_sp_eeprom_probe()
328 of_property_read_string(np, "zii,eeprom-name", &config.name); in rave_sp_eeprom_probe()
344 { .compatible = "zii,rave-sp-eeprom" },