-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #113 from system76/darp10-gpio
Use gpio to detect darp10/darp10-b
- Loading branch information
Showing
3 changed files
with
68 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Copyright 2018-2021 System76 <[email protected]> | ||
// | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
|
||
use core::ptr; | ||
|
||
// P2SB private registers. | ||
const P2SB_PORTID_SHIFT: u32 = 16; | ||
|
||
// GPIO sideband registers. | ||
const REG_PCH_GPIO_PADBAR: u32 = 0xc; | ||
|
||
pub struct Sideband { | ||
pub addr: u64, | ||
} | ||
|
||
impl Sideband { | ||
pub unsafe fn new(sbreg_phys: usize) -> Self { | ||
// On UEFI, physical memory is identity mapped | ||
Self { addr: sbreg_phys as u64 } | ||
} | ||
|
||
#[must_use] | ||
pub unsafe fn read(&self, port: u8, reg: u32) -> u32 { | ||
let offset = (u64::from(port) << P2SB_PORTID_SHIFT) + u64::from(reg); | ||
if offset < 1 << 24 { | ||
let addr = self.addr + offset; | ||
ptr::read(addr as *mut u32) | ||
} else { | ||
0 | ||
} | ||
} | ||
|
||
pub unsafe fn write(&self, port: u8, reg: u32, value: u32) { | ||
let offset = (u64::from(port) << P2SB_PORTID_SHIFT) + u64::from(reg); | ||
if offset < 1 << 24 { | ||
let addr = self.addr + offset; | ||
ptr::write(addr as *mut u32, value); | ||
} | ||
} | ||
|
||
#[must_use] | ||
pub unsafe fn gpio(&self, port: u8, pad: u8) -> u64 { | ||
let padbar: u32 = self.read(port, REG_PCH_GPIO_PADBAR); | ||
|
||
let dw1: u32 = self.read(port, padbar + u32::from(pad) * 8 + 4); | ||
let dw0: u32 = self.read(port, padbar + u32::from(pad) * 8); | ||
|
||
u64::from(dw0) | u64::from(dw1) << 32 | ||
} | ||
|
||
pub unsafe fn set_gpio(&self, port: u8, pad: u8, value: u64) { | ||
let padbar: u32 = self.read(port, REG_PCH_GPIO_PADBAR); | ||
|
||
self.write(port, padbar + u32::from(pad) * 8 + 4, (value >> 32) as u32); | ||
self.write(port, padbar + u32::from(pad) * 8, value as u32); | ||
} | ||
} |