From a Typo to the IIO Core: My LKMP Spring 2026

In this post, I’ll walk through how I got into the Linux Kernel Mentorship Program (LKMP for short). What the mentorship actually looked like week to week, my first patch (and the bug that came with it), how I found my way into the AD5504 work, and what I picked up from the community along the way.

I - The LKMP Program:

We have received 693 applications, 159 people submitted completed applications, and you have made it through!

You can’t imagine my happiness when I received this email from Shuah Khan, and found out that out of 693 applicants, only 58 of us got accepted, and I was one of them.

The Linux Foundation offers many mentorships across various open source projects, to help grow the next batch of OSS contributors and maintainers. One of those programs is the Linux Kernel Mentorship Program. Not only do you get to work on your favourite OSS project, but you also get mentorship from people whose time, honestly, I wouldn’t be able to afford for even an hour.

It’s the definition of a win-win situation.

The Offer

II - The Mentorship:

So what’s the mentorship, and how does it work? This mentorship was led by Shuah Khan, a Linux kernel maintainer and Linux Foundation Fellow, and Brigham Campbell, a past mentee himself who now works on the Linux kernel as well.

This mentorship wasn’t like a college course. The support came through weekly meetings, where we asked our questions, and where Shuah took the time to teach us tools and concepts she felt would help us go further.

Shuah encouraged us to pick one main subsystem to focus on, two at most. It’s your own path to choose, or change your mind on later if it’s not the right fit. I get into how I actually landed on my subsystem of choice, and how I went about finding things to work on once I was there, in Sections III and IV.

toughlove

III - Before we even start:

<|> The first patch:

Before any of this, I went through “A Beginner’s Guide to Linux Kernel Development” (LFD103), Shuah’s own course, and it gave me exactly what I needed to get started. It’s also free, which matters when you’re just figuring out if this whole thing is even for you.

Then, before the program started, the LFX website encourages applicants to send a patch or two to better their odds of getting accepted. So I went to read the documentation, hoping to find something to fix. First time facing the Linux kernel’s huge tree, I was overwhelmed, so I looked for anything that felt familiar. I do some robotics on the side, so I went looking for anything related to that, and before I knew it I was reading the documentation for the ADXL345 in the IIO (Industrial I/O) subsystem. Something didn’t add up: the docs said 62.5 g/LSB for the threshold, but the datasheet said 62.5 mg/LSB. So I fixed it, cleaned up a few other spelling and grammar mistakes while I was in there, and sent my first patch. And then we wait.

Good Job

<|> From the 1st patch to the 1st series:

My patch made Jonathan Cameron, the IIO subsystem maintainer, look at the file again, and that’s never a small thing. His reply opened with: “Thanks for looking at this. Unfortunately you are the victim of making people read it again and spot other issues.” Turns out my typo fixes had shaken loose something real: the documented threshold unit (62.5 mg/LSB) didn’t actually match what the driver’s scale factor could produce, and worse, auditing the driver itself showed the scale constant was wrong by roughly a factor of 100, 0.478899 in the docs and driver comments when the correct value was 0.004789. So what started as one patch became a 5-patch series, ranging from basic documentation fixes to driver changes, and even a change to the IIO core.

That core change was the hardest to land. David Lechner pushed back on my premise itself, pointing out that the enum value I wanted to add wasn’t really “missing,” and asking whether anyone actually used per-event scale attributes at all. Good question, and one I hadn’t actually answered before writing code. So I went looking at other drivers that needed the same attribute and how they handled it, and found one, mma8452.c, doing it with a static, manually wired-up sysfs attribute that bypassed the standard event_spec infrastructure entirely. With that concrete precedent in hand, David agreed the core addition made sense, and Jonathan signed off on it too.

yeaaaa

<|> Why testing isn’t optional:

I know the kernel is complex, but I still made the classic mistake of thinking “that was a simple fix, it’ll land just fine” without testing it properly. I’d added IIO_EV_INFO_SCALE to the event bitmask for both the tap-gesture events and the activity/inactivity (mag) events, but only wrote the code to actually answer a scale read for gestures. The sysfs files for the mag events, in_accel_mag_scale, in_accel_mag_adaptive_scale, still got created by the core, since the bitmask said they should exist. But reading either one just returned -EINVAL, because I’d never written the case for it. The files were there. They just didn’t work.

It hit me hard, not just because I had this image of a beginner trying to prove himself, but because I felt like I’d disappointed them, and disappointed myself, knowing I could do better. Jonathan’s exact words: “Taha assuming this bug report is correct, please up your testing game. This stuff is much easier for an author to find by actually looking at what new files are created and checking they respond as expected than it is for reviewers to figure out from patches.” So I upped my testing game, built a testing environment centered around the Raspberry Pi 5, and resent a cleaner version. To my own surprise, nobody held it against me. If anything, they were welcoming, giving me more advice and helping me land a cleaner, more complete patch.

That’s something Shuah kept mentioning during the mentorship: compile testing isn’t enough, you have to actually test your work. So we have to do our side of the work right.

stupid move

<|> The Community:

The first time I fell in love with the community was during the IIO_EV_INFO_SCALE back-and-forth with David Lechner. He didn’t just wave my core change through, he pushed back on the premise itself, asking whether anyone even used per-event scale attributes. That’s not the reaction of someone humoring a beginner; that’s someone taking a random newcomer’s suggestion seriously enough to actually interrogate it. When I came back with a real precedent from another driver, he changed his mind on the spot, no ego about it, and Jonathan signed off right after.

I fell in love with it even more once I saw how much time and effort these people put in, catching things I never would have caught myself, sometimes days apart, sometimes months apart, still following up on a thread from February in August without missing a beat. Reviewing patches again and again isn’t a formality here. It’s how the whole thing stays correct.

<|> Learning the Community norms:

Community norms extend beyond code, too. Some of what you pick up is specific to your subsystem, learned from docs or straight from peer review. Some of it is more general, things like the “include what you use” principle, or sorting headers alphabetically, conventions that show up across the whole kernel, not just IIO. Either way, you’re expected to pick it up as you go, nobody hands you a style guide on day one.

On one of the AD5504 versions, Andy Shevchenko asked, mid-review, whether a commit message had been written with AI help, since it had gotten long and over-explained (Jonathan Cameron called it a “Dostoevsky novel,” only half-joking). It was a fair question and a useful norm to learn: I do draft my own content and decisions, then use AI to check clarity and mailing-list conventions, but that pass had let things get wordy instead of tighter. The kernel community values commit messages that are concise and to the point, AI or no AI, and now I know to trim harder before sending.

So my advice: don’t mistake a maintainer’s directness for hostility. What feels like being picked on over “simple stuff” is usually just people protecting something they’ve spent years building. The Linux kernel runs because contributors keep sweating the small things, and because this community, for all its bluntness, is genuinely willing to walk a stranger through getting it right.

I love this place

IV - The 1M dollar question: How to start

The question people ask the most is: how do you find things to work on? The answer depends on you. When we started the mentorship, the first advice we got was to focus on one or two subsystems at most, with one as your primary. From there, you can use platforms like syzbot, tools like scripts/checkpatch.pl, or just read the TODOs inside the kernel source itself. I didn’t end up using any of those, which should tell you: you have plenty of tools in your toolbelt already, so use them, or make your own. Just be willing to fix whatever you find. :)

<|> What worked for me:

My way was consulting datasheets. That’s how both of my driver efforts started, the ADXL345 and the AD5504.

The AD5504 one took real digging to even name the problem properly. The datasheet describes the chip as having its own integrated precision reference, with the output range, either 0-30V or 0-60V, set entirely by a hardware pin called R_SEL. But the driver was computing its scale attribute from the VCC supply voltage instead, treating the power supply as if it were the reference. On a board where VCC didn’t match whatever the R_SEL pin had actually set, and there’s no reason it would, since VCC just powers the chip, every voltage the driver reported through IIO’s scale interface was flat wrong. Not a rounding error: a 40V supply with the chip wired for 30V output would report a scale about 30% higher than reality.

I didn’t want to just guess and send a patch, so I opened an RFC first, laying out the discrepancy with actual numbers from the datasheet math. David Lechner confirmed I’d read it correctly, and past users probably just used raw register values instead of trusting the scale attribute at all, which is honestly a little unsettling once you think about what that attribute is for. From there he sketched out how the devicetree bindings should represent the R_SEL pin, whether it’s hardwired or GPIO-controlled, and what other missing properties (vlogic-supply, clr-gpios, ldac-gpios) should get cleaned up while I was in there.

<|> It almost never stops at one patch:

Like with the ADXL345, the AD5504 work ended up becoming an 8-patch series. All I wanted was to fix how far that driver had drifted from real-world hardware, but it grew into updating its devicetree binding, reworking its header files, replacing legacy code with the IIO subsystem’s modern standard, and even fixing a data race in the driver.

That’s the short version. The longer version is that the AD5504 became a slow burn: RFC in February, then versions trickling out from March through August, each one a little more refined than the last, each one taking longer to send than the one before it, because midterms, projects, and eventually straight-up burnout kept eating into the time I had for it. There were stretches where I didn’t touch the series for two, three weeks at a time. It’s not the pace I’d have picked if school weren’t in the picture, but it’s also proof that a slow, honest pace beats rushing something out just to hit a number.

Honest Work Meme

V - Conclusion and future plans:

By the time I’m writing this, the ADXL345 series and 2 patches from the AD5504 series have already landed in Linux stable, and the rest of the AD5504 series has reached late review, now at v6. It was a great 6 months, and I wish I could’ve done even more, but life got in the way sometimes.

What I didn’t expect is how much this changed how I approach my own kernel project. Locking discipline, bisectable commits, writing for a reviewer instead of just for myself, all of that isn’t just LKMP knowledge now, it’s just how I build things. That doesn’t mean I’m done here, though. On the contrary, my journey in the Linux kernel has just begun.

A special thanks to Shuah Khan for the immense support she gave us over these 6 months. And to everyone I worked with during this period, especially Jonathan Cameron, David Lechner, Andy Shevchenko, and Krzysztof Kozlowski: your continued review, patience, and time mean the world to us.

The mentorship isn’t just about code, it’s about the community first. It was a chance to meet like-minded people, and to learn and grow together.

And if you don’t believe any of this happened: git log --author=0rayn.dev@gmail.com --oneline will find me. I’m not making this up.

The Future